пятница, 6 августа 2010 г.

Немного украденных правил блогерства

Заголовок поста
  • Заголовок начинается с заглавной буквы.
  • В конце заголовка точка не ставится.
  • Заголовок не должен содержать смайлики и !!!!!! знаки.
Тело поста
  • Текст не должен содержать смайлики.
  • Каждое новое предложение начинается с заглавной буквы.
  • В конце подзаголовков точка не ставится.
  • Между словами ставится только один пробел.
  • Знаки препинания (точки, запятые, двоеточия, точка с запятой) пишутся слитно с тем словом, после которого они стоят.
  • Между знаком препинания и следующим словом (если оно есть) ставится один пробел.
  • Если скобки () находятся в середине предложения, знаки препинания ставятся вне скобок. Если скобка заканчивает предложение, точка ставится также за скобкой. Эти же правила относятся к кавычкам.
Подвал поста
  • В подвале можно (и нужно) размещать список используемой литературы и примечания, если они есть.

Все когда нибудь ошибаются. Selenium IDE

Фукнция storeValue

Selenium IDE записал так
        ...
        $rdcategory = $this->getValue("name");
        ...
        $this->click("link=" + rdcategory);
        $this->waitForPageToLoad("30000");
        try {
            $this->assertEquals("Номер на AUTO.RU - Категория \"" + rdcategory + "\"", $this->getTitle());
        } catch (PHPUnit_Framework_AssertionFailedError $e) {
            array_push($this->verificationErrors, $e->toString());
        }
Но при запуске этого теста  выдавалась ошибка
verifytitle::testverifytitle()
PHPUnit_Framework_Exception: Response from Selenium RC server for testComplete().
ERROR: Element 0 not found.
H:\NetBeansProjects\nomer\verifytitle.php:89

Full output can be found in Output window.
Решил таким образом
        $this->click("link=$rdcategory");
        $this->waitForPageToLoad("30000");
        try {
            $this->assertEquals("Номер на AUTO.RU - Категория \"$rdcategory\"", $this->getTitle());
        } catch (PHPUnit_Framework_AssertionFailedError $e) {
            array_push($this->verificationErrors, $e->toString());

Функция verifyLocation

Selenium IDE пишет так
        try {
           $this->assertTrue((bool) preg_match('/^[\s\S]*\/map\/#lat=55\.755786&lng=37\.617633&zoom=10&type=new&date=today$/', $this->getLocation()););
        } catch (PHPUnit_Framework_AssertionFailedError $e) {
            array_push($this->verificationErrors, $e->toString());
        }
Из-за );) само собой ничего не работает -> решение очевидно :)
        try {
            $this->assertTrue((bool) preg_match('/^[\s\S]*\/map\/#lat=55\.755786&lng=37\.617633&zoom=10&type=new&date=today$/', $this->getLocation()));
        } catch (PHPUnit_Framework_AssertionFailedError $e) {
            array_push($this->verificationErrors, $e->toString());
        }
U r welcome!

вторник, 3 августа 2010 г.

Забавный длинный домен...

В спорах о максимальных значениях для тех или иных полей в системе Х и поисках подтверждений своим словам наткнулся на один забавный домен
TAK-KHARLAMOV-VALENTIN-IZ-VORONEZHA-STAL-ZNAMENIT-VESEGO-ZA-600.RU

понедельник, 2 августа 2010 г.

Функция date() - параметры аргумента format в PHP

Обозначение Описание Возвращаемое значение

День
d Day of the month, 2 digits with leading zeros 01 to 31
D A textual representation of a day, three letters Mon through Sun
j Day of the month without leading zeros 1 to 31
l (lowercase 'L') A full textual representation of the day of the week Sunday through Saturday
N ISO-8601 numeric representation of the day of the week (added in PHP 5.1.0) 1 (for Monday) through 7 (for Sunday)
S English ordinal suffix for the day of the month, 2 characters st, nd, rd or th. Works well with j
w Numeric representation of the day of the week 0 (for Sunday) through 6 (for Saturday)
z The day of the year (starting from 0) 0 through 365

Неделя
W ISO-8601 week number of year, weeks starting on Monday (added in PHP 4.1.0) Example: 42 (the 42nd week in the year)

Месяц
F A full textual representation of a month, such as January or March January through December
m Numeric representation of a month, with leading zeros 01 through 12
M A short textual representation of a month, three letters Jan through Dec
n Numeric representation of a month, without leading zeros 1 through 12
t Number of days in the given month 28 through 31

Год
L Whether it's a leap year 1 if it is a leap year, 0 otherwise.
o ISO-8601 year number. This has the same value as Y, except that if the ISO week number (W) belongs to the previous or next year, that year is used instead. (added in PHP 5.1.0) Examples: 1999 or 2003
Y A full numeric representation of a year, 4 digits Examples: 1999 or 2003
y A two digit representation of a year Examples: 99 or 03

Time
a Lowercase Ante meridiem and Post meridiem am or pm
A Uppercase Ante meridiem and Post meridiem AM or PM
B Swatch Internet time 000 through 999
g 12-hour format of an hour without leading zeros 1 through 12
G 24-hour format of an hour without leading zeros 0 through 23
h 12-hour format of an hour with leading zeros 01 through 12
H 24-hour format of an hour with leading zeros 00 through 23
i Minutes with leading zeros 00 to 59
s Seconds, with leading zeros 00 through 59
u Microseconds (added in PHP 5.2.2) Example: 654321

Timezone
e Timezone identifier (added in PHP 5.1.0) Examples: UTC, GMT, Atlantic/Azores
I (capital i) Whether or not the date is in daylight saving time 1 if Daylight Saving Time, 0 otherwise.
O Difference to Greenwich time (GMT) in hours Example: +0200
P Difference to Greenwich time (GMT) with colon between hours and minutes (added in PHP 5.1.3) Example: +02:00
T Timezone abbreviation Examples: EST, MDT ...
Z Timezone offset in seconds. The offset for timezones west of UTC is always negative, and for those east of UTC is always positive. -43200 through 50400

Полная дата и время
c ISO 8601 date (added in PHP 5) 2004-02-12T15:19:21+00:00
r » RFC 2822 formatted date Example: Thu, 21 Dec 2000 16:01:07 +0200
U Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT) See also time()

понедельник, 19 июля 2010 г.

Установка PEAR под Windows

Согласно мануалу нужно было запустить
php_home\go-pear.bat
но в моём случае, как и во многих других случаях на просторах всемирной паутины, запуск ни к че6му не привёл и сказал примерно это
C:\Program Files\PHP>go-pear.bat
phar "C:\Program Files\PHP\PEAR\go-pear.phar" does not have a signatureДля продолжения нажмите любую клавишу . . .


поэтому побороздив гуглояндексные результаты сделал в go-pear.bat так
rem @ECHO OFF
rem set PHP_BIN=php.exe
rem %PHP_BIN% -d output_buffering=0 PEAR\go-pear.phar
rem pause

@ECHO OFF
set PHP_BIN=php.exe
%PHP_BIN% -d output_buffering=0 -d phar.require_hash=0 PEAR\go-pear.phar
pause
запустил и получил
C:\Program Files\PHP>go-pear.bat
phar "C:\Program Files\PHP\PEAR\go-pear.phar" does not have a signatureДля продолжения нажмите любую клавишу . . .

C:\Program Files\PHP>go-pear.bat

C:\Program Files\PHP>rem @ECHO OFF

C:\Program Files\PHP>rem set PHP_BIN=php.exe

C:\Program Files\PHP>rem  -d output_buffering=0 PEAR\go-pear.phar

C:\Program Files\PHP>rem pause

Are you installing a system-wide PEAR or a local copy?
(system|local) [system] : local
Please confirm local copy by typing 'yes' : yes

Below is a suggested file layout for your new PEAR installation.  To
change individual locations, type the number in front of the
directory.  Type 'all' to change all of them or simply press Enter to
accept these locations.

 1. Installation base ($prefix)                   : C:\Program Files\PHP
 2. Temporary directory for processing            : C:\Program Files\PHP\tmp
 3. Temporary directory for downloads             : C:\Program Files\PHP\tmp
 4. Binaries directory                            : C:\Program Files\PHP
 5. PHP code directory ($php_dir)                 : C:\Program Files\PHP\pear
 6. Documentation directory                       : C:\Program Files\PHP\docs
 7. Data directory                                : C:\Program Files\PHP\data
 8. User-modifiable configuration files directory : C:\Program Files\PHP\cfg
 9. Public Web Files directory                    : C:\Program Files\PHP\www
10. Tests directory                               : C:\Program Files\PHP\tests
11. Name of configuration file                    : C:\Program Files\PHP\pear.ini
12. Path to CLI php.exe                           : .

1-12, 'all' or Enter to continue:
тут жмём просто Enter
"".\php.exe"" не является внутренней или внешней
командой, исполняемой программой или пакетным файлом.

*WARNING*
We found php.exe under ., it uses an unknown SAPI. PEAR commandline
tool has not been tested with it, if you have a CLI (or CGI) php.exe available,
we strongly recommend using it.

Beginning install...
Configuration written to C:\Program Files\PHP\pear.ini...
Initialized registry...
Preparing to install...
installing phar://C:/Program Files/PHP/PEAR/go-pear.phar/PEAR/go-pear-tarballs/Archive_Tar-1.3.3.tar...
installing phar://C:/Program Files/PHP/PEAR/go-pear.phar/PEAR/go-pear-tarballs/Console_Getopt-1.2.3.tar...
installing phar://C:/Program Files/PHP/PEAR/go-pear.phar/PEAR/go-pear-tarballs/PEAR-1.8.0.tar...
installing phar://C:/Program Files/PHP/PEAR/go-pear.phar/PEAR/go-pear-tarballs/Structures_Graph-1.0.2.tar...
installing phar://C:/Program Files/PHP/PEAR/go-pear.phar/PEAR/go-pear-tarballs/XML_Util-1.2.1.tar...
install ok: channel://pear.php.net/Archive_Tar-1.3.3
install ok: channel://pear.php.net/Console_Getopt-1.2.3
install ok: channel://pear.php.net/Structures_Graph-1.0.2
install ok: channel://pear.php.net/XML_Util-1.2.1
install ok: channel://pear.php.net/PEAR-1.8.0
PEAR: Optional feature webinstaller available (PEAR's web-based installer)
PEAR: Optional feature gtkinstaller available (PEAR's PHP-GTK-based installer)
PEAR: Optional feature gtk2installer available (PEAR's PHP-GTK2-based installer)
PEAR: To install optional features use "pear install pear/PEAR#featurename"

** WARNING! Old version found at C:\Program Files\PHP, please remove it or be sure to use the new c:\program files\php\pear.bat command

The 'pear' command is now at your service at c:\program files\php\pear.bat
Для продолжения нажмите любую клавишу . . .

C:\Program Files\PHP>
дальше
php_home\pear upgrade PEAR
и результат
C:\Program Files\PHP>pear upgrade PEAR
downloading PEAR-1.9.1.tgz ...
Starting to download PEAR-1.9.1.tgz (293,587 bytes)
.............................................................done: 293,587 bytes
downloading Archive_Tar-1.3.7.tgz ...
Starting to download Archive_Tar-1.3.7.tgz (17,610 bytes)
...done: 17,610 bytes
downloading Structures_Graph-1.0.3.tgz ...
Starting to download Structures_Graph-1.0.3.tgz (30,191 bytes)
...done: 30,191 bytes
upgrade ok: channel://pear.php.net/Archive_Tar-1.3.7
upgrade ok: channel://pear.php.net/Structures_Graph-1.0.3
upgrade ok: channel://pear.php.net/PEAR-1.9.1
PEAR: Optional feature webinstaller available (PEAR's web-based installer)
PEAR: Optional feature gtkinstaller available (PEAR's PHP-GTK-based installer)
PEAR: Optional feature gtk2installer available (PEAR's PHP-GTK2-based installer)
PEAR: To install optional features use "pear install pear/PEAR#featurename"

C:\Program Files\PHP>
Готово!

пятница, 2 июля 2010 г.

Причины дающие право приостановить тестирование

Очередная зарисовка Andy Glover'а на тему тестирования и причин остановки тестирования...


  • Очень много багов в тестируемом объекте
  • Вам нужно отдышаться
  • "И настало время РЕЛИЗА" :)
  • В системе есть одна большая мамочка-блокировочка
  • Рабочее время кончилось
  • Корпоративчик
  • Не платят за работу
  • Выполнены все запланированные мероприятия
  • Вы не можете найти больше ни одного бага
  • Появился новый член семьи как у Энди :)

пятница, 25 июня 2010 г.

Горе рекламодатель

В блоге у меня крутится реклама от Adsense, само собой она бросается в глаза и обычно только раздражает, но сегодня она меня порадовала, смотрите, думаю будет понятно чем...

Сказка о том, как Google Maps ищет Жопы по всему миру

Тестирую некий web-проект который использует Google Maps API.

В душе я ребёнок... поэтому появляются всякие "жопы" и прочие "пиписьки" во время работы :) не кидайте камнями! На этот раз проверку на "жопу" не прошли Google Maps, они благополучно определили, что "Жопа" находится в местечке Les Joppes, Saint-Hilaire, France, внимание:



 
 
Причём на самих Google Maps это чудесное местечко не ищется :(

среда, 16 июня 2010 г.

Зарисовки на тему разработки ПО

Разбираясь на рабочем компьютере в папках аля My Documents/tmp/downloads наткнулся на пару забавных картинок о разработке


и о баге

вторник, 15 июня 2010 г.

Вот к чему приводят игры с цветами...

Лето... Погода совсем не радует, а тут ещё унылые цвета mantis'а на работе.
А почему бы их не изменить... может будет и работать приятней?

И понеслось... нашёл таблицу цветов... открыл на редактирование config_inc.php, для тех кто не знает - это конфигурационный файл matis'а, и начал играться с цветами....

Совмещал приятное с полезным где-то около получаса... В итоге получилось так:

До

После

Ну и собственно
# цветовая схема статусов отчётов
    $g_status_colors = array(
        # новый
        'new' => '#FA8072',
        # нужен отклик
        'feedback' => '#EE1289',
        # рассмотрен
        'acknowledged' => '#ffd850',
        # подтвержден
        'confirmed' => '#ffffb0',
        # назначен
        'assigned' => '#A4D3EE',
        # обработан
        'resolved' => '#7FFF00',
        # закрыт
        'closed' => '#B5B5B5');

Таблица кодов цветов html, буквенное написание и коды цветов в RGB

Недавно ковыряя mantis, захотелось поиграться с цветами... Благо достаточно быстро нашлась "таблица кодов цветов html, буквенное написание и коды цветов в RGB" и буйству моей фантазии не было предела :)

Ну вот решил выложить, мало ли кому будет нужно....

          Написание Цвет                     R G B Код цвета для HTML
Snow Snow 255 250 250 #FFFAFA
GhostWhite GhostWhite 248 248 255 #F8F8FF
WhiteSmoke WhiteSmoke 245 245 245 #F5F5F5
Gainsboro Gainsboro 220 220 220 #DCDCDC
FloralWhite FloralWhite 255 250 240 #FFFAF0

пятница, 11 июня 2010 г.

Во истину быдлокод

Немного теории:
Быдлокодер (aka горе-программист, индус; англ. Code Monkey) — это человек, который считает рекурсию мемом башорга и не знает основных алгоритмов и тонкостей языка, на котором пишет. Поэтому быдлокодер использует неочевидные и абсурдные решения, а зачастую вообще использует исключительно готовые алгоритмы и программы, находя их на OpenSource.net или сайтах, подобных CodeGuru.
И ещё:
Быдло -  хам; тупой, грубый, неотёсанный, бескультурный человек, движимый прежде всего инстинктами, пренебрегающий разумом и моралью
Характерной чертой быдлокодера является отсутствие языковой грамотности...
На просторах всемирной паутины, а в особенности на ресурсах связанных с тестированием часто встречаются скриншоты олицетворяющие невнимательность и бездумность многих разработчиков, вот и я решил плюнуть в их сторону...

Вуаля...

Ну как Вам, нравится? :)


З,Ы, немного поигрался с цветом оригинального скриншота, дабы не нарушать всяких там прав :)

суббота, 5 июня 2010 г.

Автоматическое занесение отчётов в BTS при нахождении автотестами ошибок

Немного потыкав по клавишам всё же воплотил в жизнь идею с автоматическим занесением отчётов об ошибках в багтрекинговую систему, в моём случае это mantis.

Суть идеи такова... гонятся авто-тесты в связке JUnit + Selenium RC, которые в случае нахождения ошибки автоматом создают отчёты об ошибка в багтрекере, как Вам? :)

Для реализации используем связку двух классов в одном из которых уже описанный способ создания скриншотов при прогоне тестов, а  во втором тест создающий отчёты о найденных ошибках.

Итак.... гоним первый тест
package seleniumtests;

import com.thoughtworks.selenium.*;
import java.awt.AWTException;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import javax.imageio.ImageIO;

/**
 *
 * @author makeenkov
 */
public class googletest extends SeleneseTestCase {

    public static String what;
    public static String filename;
    String time = new SimpleDateFormat("dd.MM.yyyy_HH.mm.SS").format(new java.util.Date());

    void recordStep(String name) throws AWTException, IOException {
        File screenshot = new File(new File("."), name + ".png");
        Dimension screenDim = Toolkit.getDefaultToolkit().getScreenSize();
        BufferedImage image = new Robot().createScreenCapture(new Rectangle(0, 0, screenDim.width, screenDim.height));
        try {
            ImageIO.write(image, "png", screenshot);
        } catch (IOException ignore) {
            ignore.printStackTrace();
        }
    }

    @Override
    public void setUp() {
        selenium = new DefaultSelenium("0.0.0.0", 4444, "*firefox", "http://www.google.ru/");
        selenium.start();
    }

    public void test() throws Exception {
        System.out.println("Итак начнём: " + time);
        selenium.open("http://www.google.ru/");
        selenium.waitForPageToLoad("30000");
        selenium.selectWindow("Google");
        selenium.type("q", "black and white");
        selenium.click("btnG");
        selenium.waitForPageToLoad("30000");
        if (selenium.isTextPresent("Расходные материалы для лазерных принтеров") && selenium.isTextPresent("blacknwhite.ru") && selenium.isTextPresent("Картриджи по оптовым ценам: 589-49-04 Расходные материалы для лазерных принтеров.")) {
            System.out.println("Сайт в индексе в топ-5");
        } else {
            System.out.println("Сайт выпал из индекса или из топ-5");
            selenium.windowFocus();             //Gives focus to the currently selected window
            selenium.windowMaximize();           //Resize currently selected window to take up the entire screen
            recordStep("индекс_топ-5_" + time);
            what = "Сайт выпал из индекса или из топ-5" + time;
            filename = "индекс_топ-5_" + time + ".png";
        }
        selenium.close();
        selenium.stop();
        System.out.println("Конец: " + new SimpleDateFormat("dd.MM.yyyy HH.mm.SS").format(new java.util.Date()));
    }
}
который в случае ошибки на выходе даёт нам скриншот и переменные содержащие суть ошибки.
Этот класс вызывается из второго класса
package seleniumtests;

import com.thoughtworks.selenium.*;
import junit.framework.Test;
import junit.framework.TestSuite;

/**
 *
 * @author makeenkov
 */
public class obts extends SeleneseTestCase {

//    googletest gt = new googletest();

    @Override
    public void setUp() {
        selenium = new DefaultSelenium("0.0.0.0", 4444, "*firefox", "http://www.bugtrack-online.com/");
        selenium.start();
    }
   
    public void test() throws Exception {
        System.out.println(googletest.what);
        System.out.println(googletest.filename);
        if (googletest.what == null) {
            System.out.println("Сайт в индексе в топ-5");
        } else {
            selenium.open("/login_page.php");
            selenium.waitForPageToLoad("30000");
            selenium.type("username", "йцукен");
            selenium.type("password", "123456");
            selenium.click("//input[@value='Войти в систему']");
            selenium.waitForPageToLoad("30000");
            selenium.click("link=Online Bug Tracking System");
            selenium.waitForPageToLoad("30000");
            if (selenium.isTextPresent("По всем вопросам пишем в этот отчёт...")) {
            } else {
                selenium.select("project_id", "label=Online Bug Tracking System");
                selenium.waitForPageToLoad("30000");
                selenium.click("//input[@value='Переключиться']");
                selenium.waitForPageToLoad("30000");
            }
            selenium.click("link=создать отчет");
            selenium.waitForPageToLoad("30000");
            selenium.select("category", "label=Категории 1");
            selenium.select("reproducibility", "label=всегда");
            selenium.select("severity", "label=значительная");
            selenium.type("summary", "summary="+googletest.what);
            selenium.type("description", "description="+googletest.what);
            selenium.type("file", "D:\\NetBeansProjects\\seleniumtests\\"+googletest.filename);
            selenium.click("//input[@value='Создать отчет']");
            selenium.waitForPageToLoad("30000");
        }
        selenium.close();
        selenium.stop();
    }

    public static Test googletest() {
        return (Test) new TestSuite(googletest.class);
    }

    public static Test obts2() {
        return (Test) new TestSuite(obts.class);
    }

    public static void main(String args[]) {
        junit.textui.TestRunner.run(googletest());
        junit.textui.TestRunner.run(obts2());
    }
}
который в свою очередь вытягивает переменные и скриншот, а дальше создаёт на основе полученных данных отчёт в багтрекинговой системе.

В итоге получаем вот такого вида отчёт в системе отслеживания ошибок

пятница, 4 июня 2010 г.

Создание скриншотов в случае нахождения тестами ошибок

С недавних пор пишу тесты на java для связки JUnit + Selenium RC.

В какой-то момент появилась идея заносить отчёты в систему отслеживания ошибок прямо из тестов... но прикинув пока решил, что очень громоздко получается :)


И вот во время прикидывания наткнулся на интересный кусочек кода, создающий скриншоты и сохраняющий их в файлы...
void recordStep(String name) throws AWTException {
    File screenshot = new File(new File("."), name + ".png");
    Dimension screenDim = Toolkit.getDefaultToolkit().getScreenSize();
    BufferedImage image = new Robot().createScreenCapture(new Rectangle(0, 0, screenDim.width, screenDim.height));
    try {
        ImageIO.write(image, "png", screenshot);
    } catch (IOException ignore) {
        ignore.printStackTrace();
    }
}
Объяснять как работает этот метод не буду, т.к. во-первых, многие и сами понимают, а во-вторых, это сделали лучше меня там, где я этот код нашёл:
Здесь все очень просто. В качестве параметра мы передаем имя файла для скриншота.
Потом:
-объявляем файл, в качестве директории я использую здесь текущую( можно сделать в качестве параметра).
-получаем размеры скриншота.
-в BufferedImage помещаем скриншот, сделанный с помощью возможностей класса Robot.
- и наконец - создаем(помещаем) наш скриншот в сам png-файл.
И вот такое чудо получается:
import com.thoughtworks.selenium.*;
import java.awt.AWTException;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import javax.imageio.ImageIO;
import junit.framework.Test;
import junit.framework.TestSuite;
/**
 *
 * @author makeenkov
 */
public class bnwintop extends SeleneseTestCase {
    String time = new SimpleDateFormat("dd.MM.yyyy HH.mm.SS").format(new java.util.Date());
    void recordStep(String name) throws AWTException {
        File screenshot = new File(new File("."), name + ".png");
        Dimension screenDim = Toolkit.getDefaultToolkit().getScreenSize();
        BufferedImage image = new Robot().createScreenCapture(new Rectangle(0, 0, screenDim.width, screenDim.height));
        try {
            ImageIO.write(image, "png", screenshot);
        } catch (IOException ignore) {
        ignore.printStackTrace();
        }
    }
    @Override
    public void setUp() {
        selenium = new DefaultSelenium("localhost", 4444, "*opera", "http://www.google.com");
        selenium.start();
    }
    public void test() throws Exception {
        System.out.println("Итак начнём: " + time);
        selenium.open("/");
        selenium.waitForPageToLoad("30000");
        selenium.type("q", "black and white");
        selenium.click("btnG");
        selenium.waitForPageToLoad("30000");
        if (selenium.isTextPresent("Расходные материалы для лазерных принтеров") && selenium.isTextPresent("blacknwhite.ru") && selenium.isTextPresent("Картриджи по оптовым ценам: 589-49-04 Расходные материалы для лазерных принтеров.")) {
            System.out.println("Сайт в индексе в топ-5");
        } else {
            System.out.println("Сайт выпал из индекса или из топ-5");
            selenium.windowFocus();             //Gives focus to the currently selected window
            selenium.windowMaximize();           //Resize currently selected window to take up the entire screen
            recordStep("индекс_топ-5_" + time);
        }
        selenium.close();
        selenium.stop();
        System.out.println("Конец: " + new SimpleDateFormat("dd.MM.yyyy HH.mm.SS").format(new java.util.Date()));
    }
    public static Test EnterGoogle() {
        return (Test) new TestSuite(bnwintop.class);
    }
    public static void main(String args[]) {
        junit.textui.TestRunner.run(EnterGoogle());
    }
}
Этот тест контролирует нахождение сайта в топ-5 googl'а и в случае ошибки делает скриншот с участниками топ-5, собственно вот, файл индекс_топ-5_05.06.2010 16.50.155.png


Может быть не всегда применимо, но мне нравится :) постараюсь развить идею с автоматическим занесением отчётов, тогда и отпишусь....

среда, 26 мая 2010 г.

Картриджи для тестировщиков

Не совсем стандартная для блога о тестировании тема, но с другой стороны почему не сделать добро себе и другим!

Вообщем суть проста, есть интернет-магазин BlacknWhite занимающейся продажей оригинальных картриджей для лазерных принтеров, картриджей для копиров, а так же других расходных материалов для оргтехники по оптовым ценам.

Т.к. я имею некое отношение к этому интернет-магазину, то смею его немного по рекламировать и по обещать скидки всем тестировщикам :)





пятница, 23 апреля 2010 г.

Эдакий жизненный цикл бага

аботая во фрилансе предлагаю Всем заказчикам которые используют или собираются использовать Exel в качестве багтрекера предлагаю поднятый и немного допиленный мной Mantis располагающийся здесь. Но вот как выясняется, многие и очень многие люди варящиеся в сфере разработки не знают как ей пользоваться и что бывает с отчётом об ошибке... Именно поэтому решил выложить свой вариант ЖЦ отчёта об ошибке в системе отслеживания ошибок.


А вот и схема жизни бага...


Схема меняется в зависимости от организации процесса разработки, но скелет в общих чертах везде одинаковый.


З,Ы, первоначальный вариант
З,З,Ы, второй вариант

четверг, 22 апреля 2010 г.

Чудеса фриланса

А вот и он, очередной заказчик с фриланса. Но этот заказчик меня удивил и поэтому я решил поведать о нём здесь...
я: Вы тут?
заказчик: да
заказчик: вы специалист по Drupal
я: я по тестированию....
заказчик: а, без проблем
ВАКАНСИЯ ВЭБ ТЕСТЕР:
тип работы: постоянная, удаленная, свободный график.
Для тестирования сайта нттр://******.ру требуется ВЭБ ТЕСТИРОВЩИК
.....
бла бла бла
.....
в день можно по 60 ошибок находить, стоимость обсуждается  после собеседования,
.....
бла бла бла
.....
Бюджет: 9000р из 30 дневного расчета, по 60 ошибок в день
я: эм, странный расчёт...
заказчик: мы платим за найденные ошибки
я: просто Вы так сказали, как буд-то у Вас заложено 1800 ошибок в систему  
Впервые встречаюсь с таким подходом к оплате, сдельщина на фрилансе - это нормально, но вот сдельный fix - это уже довольно странно.

на следующий день...
заказчик: Добрый день. ошибок в системе  свыше 1000, точно.
я: :)
я: Доброго времени!
я: Спасибо! По сдельной я работать не буду...
На самом деле смущает не сдельщина, а то, что впереди видно определённое кол-во ошибок в системе :)

прошло ещё немного времени...
я: а сама разработка как построена?
я: почему Вам тестер нужен ещё и на сдельщину
заказчик: ошибок свыше 1000
заказчик: сами не справляемся
я: :)
я: а как Вы кол-во ошибок определяете?
заказчик: сюда входят все ошибки, вплодь до орфографических, верстка и пр
я: ясно, это конечно странный момент
заказчик: ни чего странного , нужно исправлять все ошибки.
я: да это понятно, я просто не совсем понимаю, как Вы узнали кол-во ошибок общее
заказчик: лично исправлял

Ну вот, что значит ответ "я лично исправлял" - это больше похоже на я лично делал эти ошибки :) Да и зачем нужен тестировщик в такой ситуации? ведь если известно сколько ошибок, то должно быть известно где их искать :) И кстати небольщой момент, тестировщик в группе уже есть, но он не справляется... что же там за тестировщик, который в кишащей багами системе (это вывод из слов заказчика) не может их найти быстрее, чем 60 штук в день!

суббота, 10 апреля 2010 г.

Песня "happy birthday"

Немного офф-топа.

Казалось бы какая проблема, найти песню "happy birthday"... оказалось проблемой. Песен много, называются все по-разному, а по факту это десяток оригинальных песен.

Покопался, нашёл штук 30, удалил дубликаты и вот... может кому понадобится... архив
 с 13 песнями! Пользуйтесь... поздравляйте!



Ну и один из вариантов текстов песни:
Happy Birthday
Happy Birthday!
Happy Birthday to you!
Happy Birthday!
Happy Birthday to you!

Well it's time to celebrate your birthday,
It happens every year.
We'll eat a lot of broccoli, and drink a lot of beer.
You should be good and happy that there's somethin' you can eat.
A million people every day are starvin' in the street.
Your daddy's in the gutter with the wretched and the poor.
Your mama's in the kitchen with a can of Cycle Four.
There's garbage in the water,
There's poison in the sky.
I guess it won't be long before we're all gonna die!

Happy Birthday!
Happy Birthday to you!
Happy Birthday!
Happy Birthday to you!

Well, what's the matter, little friend, you think this party is the pits?
Enjoy it while you can.
We'll soon be blown to bits!
The monkeys in the Pentagon are gonna cook our goose.
Their finger's on the button, all they need is an excuse.
It doesn't take a military genius to see
We'll all be Crispy Critters after World War III.
There's nowhere you can run to,
Nowhere you can hide.
When they drop the big one,
We all get fried.

Come on, boys and girls, sing along, okay?

Happy Birthday!
Happy Birthday to you!
Happy Birthday!
Happy Birthday to you!

Well, there's a punk in the alley, and he's lookin' for a fight.
There's an Arab on the corner buyin' everything in sight.
There's a mother in the ghetto with another mouth to feed.
Seems that everywhere you look today, there's misery and greed.
I guess you know the Earth is gonna crash into the sun,
But that's no reason why we shouldn't have a little fun.
So if you think it's scary, if it's more than you can take.

пятница, 9 апреля 2010 г.

IP в шестнадцатеричном виде

С недавних пор у нас на собеседованиях обязательным является вопрос на знание того, как выглядит IP-адрес (IPv4). Обусловлено это, во-первых, тем, что специфика нашей системы требует таких знаний, хотя раньше этот факт не наталкивал нас на такие вопросы ибо все думали, что в наше время человек варящийся в сфере ИТ не может не знать как выглядит IP-адрес, а во-вторых, после случая с одним кандидатом который на просьбу написать какой-нибудь IP-адрес из головы написал дословно 632.7201.12. Скажу Вам, что многие кандидаты приходящие даже не на 30 000 пишут хоть и правильный IP-адрес, но со скрипом.

Так вот придя с одного собеседования, зашёл разговор о том, что кандидаты не знают, как выглядит IP-адрес и один гуру, сказал, а чтобы Вы делали, если кандидат написал IP в виде 7f000001. По сути ничего необычного, всего лишь IP-адрес в шестнадцатеричном виде, но я лично не мог подумать или просто никогда не задумывался, что браузеры спокойно "хавают" такое написание….

К примеру:
localhost - http://0x7f000001
Я.Ру - http://0x4d581508

среда, 7 апреля 2010 г.

Ревью тест-кейсов

Ну вот, мы наконец и подошли, а точнее даже сказать доросли до ревью тест-кейсов. Попробовали выделить основные моменты на которые необходимо обращать внимание при написании и соответственно при ревью тест-кейсов. Выделенные моменты сделали вопросами на которые нужно ответить сделав ревью тест-кейсов.

Вопросы на которые отвечает ревью:
  1. Правильно ли выставлено плановое время? 
    • под плановым временем понимается время выставленное тест-дизайнером для прохождения конкретного тест-кейса одним манки-тестером
  2. Есть ли завязка на другие кейсы?
    • ...
  3. Наличие и понятность начальных условий. 
    • это особенно важный момент, т.к. система находящаяся в разных состояниях на момент начала прохождения тест-кейса может выдавать разные результаты, хотя это зависит от конкретной системы
  4. Понятность не подготовленному сотруднику…
    • тут всё зависит от того, кто проходит тест-кейсы и каков уровень этих сотрудников по отношению к уровню тест-дизайнеров, т.е. если манки вовсе не манки, а хорошо знающие функционал системы сотрудники, то для них разжёвывания в тест-кейсах только в минус, соответственно если манки именно манки, то...
  5. Есть зацикливание? – обороты вида "…проверяем шаги 1-3…
    • украдено: Это миф. Тест кейс зацикливать нельзя. То есть писать «Repeat steps 1-3» не стоит. А собственно почему? Только потому, что это прерывает последовательность шагов? Вот фигня то. Тест кейс – это обычный сценарий действий, и если действительно нужно повторить шаг с первого по третий, то почему бы не повторить? Но вот если шаг 1-3 говорит о том, что действие надо сделать с объектом «А», а нужно повторить эти шаги для объекта «Б», тогда придется писать эти шаги снова, но уже для объекта «Б». Так же придется делать, если количество шагов больше семи (магическая цифра, найденная психологами или психиатрами).
  6. Полнота проверки (возможно пропущенные тестовые ситуации).
    • действуем по принципу "одна голова хорошо, а две лучше"
  7. И напоследок, руководитель проведя ревью сможет оценить эффективно ли потрачено время
Как и прежде, буду рад комментариям и критике...

вторник, 23 марта 2010 г.

Первые шаги недогуру. Автоматизированное тестирование

Ну вот, я руководитель отдела тестирования... И что? Ну конечно же первые трудности.

Группа автоматизированного тестирования...

До недавнего времени, все мои знания об автоматизации и подходах была сведена к изучению Selenium'а на уровне Selenium IDE :) и естественно встретив группу автоматизированного тестирования, даже хорошо отлаженную, я бы был удивлён... Но, само собой, откуда взяться отлаженной, на вот Серёженька, возьми то, что есть и будь добр наладь.

Итак, передо мной группа, вроде бы, что-то автоматизирующая, но не понятно с какой целью, как, в какой последовательности и главное Зачем?

Также интересный и думаю многим знакомый момент, группа вроде бы как-то работает и даёт какие-то результаты, но если человек варящейся в этой каше как-то сможет понять что к чему и какие результаты есть, то руководству необходимы цифры, отчёты, диаграммы... а как построить диаграмму по работе группы работающий "не понятно с какой целью, как, в какой последовательности и главное Зачем?"...

Таким образом среди первых задач в работе с группой автоматизации понять Зачем?, на основания "зачема" определится с целями и тогда уже попытаться построить работу и выдать первые результаты в том числе и отчёты, диаграммы и прочее...

понедельник, 15 марта 2010 г.

Несколько вопросов на собеседовании в Google и не только

В тему собеседований и не только...

Вопрос: Сколько шариков для гольфа поместится в школьный автобус?
Это один из вопросов, которые в Google спрашивают, чтобы посмотреть, каким образом соискатель ищет решение проблемы. Читатель Мэт Бьючамп (Matt Beauchamp) нашёл хороший ответ: 
Я представил стандартный школьный автобус шириной 8 футов, высотой 6 футов и длиной 20 футов – я знаю это из-за тысяч часов, проведённых в автобусе во время пробок. Это значит 960 кубических футов, 1728 кубических дюймов в кубическом футе, а это значит около 1.6 миллионов кубических дюймов. Я подсчитал, что объём мяча для гольфа около 2.5 кубических дюймов (4/3 * pi * .85), так как радиус мяча - .85 дюймов. Разделив 1,6 миллиона на 2,5 кубических дюйма, мы получим 660 000 шаров. Однако, поскольку там есть еще сиденья и прочая ерунда, занимающая свободное место, а также сферическая форма мяча означает, что будет достаточно много свободного места между ними. Я уменьшил значение до 500 000 шаров. Звучит забавно. Я думаю, что смог быть поместить не более 100 тысяч, но я верю в свои математические способности. Конечно, если бы мы говорили об автобусе, на котором ездил Джордж Буш в школу, это было бы половина… или 250 000 шаров.
Вопрос: За сколько денег вы помоете все окна в Сиэтле?
Предлагается не тупить при ответе и ответить не умно, а красиво и хитро. Мы бы сказали 10$ за окно.


Вопрос: Разработайте план эвакуации из Сан Франциско.
Опять, здесь смотрят, как соискатель атакует проблему. Статья источник предлагает начать рассуждения с вопроса: "какое бедствие запланировано на сегодня"?

Вопрос: Сколько раз за день стрелки часов пересекаются?
22 раза. Из WikiAnswers:
00:00
1:05
2:11
3:16
4:22
5:27
6:33
7:38
8:44
9:49
10:55
12:00
13:05
14:11
15:16
16:22
17:27
18:33
19:38
20:44
21:49
22:55

Вопрос: Объясните значение выражения “dead beef”
Правильный ответ от читателя:
DEADBEEF шестнадцатиричное значение, которое использовалось для дебаггинга во времена больших мейнфреймов, потому что этот маркер было очень легко найти в шестнадцатиричных дампах. Большинство людей с компьютерным образованием должны были видеть это как минимум на уроках изучения ассемблера, вот почему в Google ожидают, что Разработчик ПО знает об этом.
“0xDEADBEAF” (“dead beef”) использовался система IBM RS/6000, Mac OS на 32-битном процессоре PowerPC и Commodore Amiga в качестве волшебного значения для дебага. На Solaris от Sun Microsystem, это значение обозначало свободную память ядра. На OpenVMS, работающей на процессорах Alpha, DEAD_BEEF можно увидеть, нажав CTRL-T.
Вопрос: Человек направил свой автомобиль на отель, но потерпел неудачу. Почему?
Он застрял на бордюре. По-моему, забавно....

Вопрос: У вас есть 8 шаров одинакового размера…7 из них одинакового веса, а один весит чуть больше остальных. найти мяч, который тяжелее остальных, используя баланс и только два взвешивания?
Возьмите 6 из 8 мячей и положите по 3 на каждую сторону весов. Если тяжёлый мяч в этой группе шаров, у вас есть ещё 2, которые надо положить на весы и решить задачу. Если тяжёлый шар в первой группе из 6 шаров, берите 3, которые тяжелее. Из этих трёх два положите на весы. Если один перевесит — то вы его нашли. Если они весят одинаково, то значит ваш мяч — тот, который вы отложили.

Вопрос: Объясните что такое База Данных в трёх предложениях, так как это сделал бы ребёнок.
Суть такая, если человек написал в резюме умное слово и прочитал о нём в Википедии, то большая вероятность, что ему будет трудно объяснить значение простыми словами.

Вопрос: Вы были уменьшены до размеров 5-центовой монеты…и ваша масса была пропорционально уменьшена соответственно вашей плотности. Теперь вас бросили в пустой стакан блендера. Ножи начнут движение через 60 секунд. Что делать?
Этот вопрос оценивает креативность соискателя. Статья источник предлагает попробовать сломать электромотор.

Своровано отсюда

понедельник, 1 марта 2010 г.

Как использовать scrum board плагин для mantis

Недавно, я представил Вашему вниманию своё детище - scrum board интегрированный в mantis и вкратце рассказал о том, что нужно сделать, чтобы "детище" работало.

В этой заметке я хочу рассказать о том, как организовать работу в баг трекере, чтобы максимально плодотворно использовать "детище".

Итак, по порядку...

Допустим в Вашей компании есть несколько постоянных проектов и эти проекты дорабатываются с использованием методологии scrum или проекты постоянно новые и каждый тоже по scrum'у работает. Тогда делаем так...

Вы в своём mantis'е создаёте проект, например, с названием "Проекты в производстве" - этот проект будет хранить в себе глобальные задачи или же можно сказать будет хранилищем скрамов.


Создаём отчёт (теперь этот отчёт является скрам сессией) в проекте под названием "Проекты в производстве" и добавляете в качестве тегов названия историй этого скрама.


Итак, у нас есть скрам сессия, если можно я её буду назвыать так и привязанные к ней истории. Уже неплохо... :)

Теперь, все баги, задачи, тикеты, отчёты, вопросы в вашем баг трекере которые имеют тег=названию истории (если Вы ещё не забыли истории мы указываем в качестве тегов к головному отчёту) будут отображаться в scrum board'е этой скрам сессии как задачи по истории тег которой Вы привязали.



В отчётах-задачах не забывайте проставлять планируемое время на выполнение задачи в рамках скрам сессии. Это время будет отображаться в srum board'е. Также для удобства связывайте все отчёты-задачи по скраму с головным отчётом, чтобы открыв головной отчёт можно было увидеть как истории этой скрам сессии посмотрев на теги, так и все задачи по этой скрам сессии.


Теперь у нас есть головной отчёт - скрам сессия, истории - теги и задачки - баги раскиданные по багтрекеру и все эти сущности связаны тегами и связями, простите за тафтологию.

Пойдёмте, посмотрим на scrum board... Кликаем по ссылке scrum board в главном меню mantis'а, среди проектов выбираем "Проекты в производстве" и дальше выбираем нужную нам скрам сессию. Переходим к scrum board'у...

  • Столбец History включает в себя все теги истории которые привязаны к головному отчёту.
  • Столбец To Do включает в себя все отчёты-задачи со статусом новый (new).
  • Столбец Doing включает в себя все отчёты-задачи со статусами нужен отклик, рассмотрен, подтверждён, назначен (feedback, acknowledged, confirmed, assigned).
  • Столбец Testing включает в себя все отчёты-задачи со статусом решён или обработан (resolved), у кого как в mantis'е заведено.
  • Столбец Closed соответственно включает в себя все отчёты-задачи со статусом закрыто (closed).

Для столбцов To Do, Doing, Testing, Closed считается суммарное время, т.е., например, сколько запланировано времени в скрам-сессии на новые задачи. А внизу отдельной табличкой вынесено суммарное время на историю по всем типам задач.

Вот вроде бы и всё....

З,Ы, Если что-то забыл или кому-то непонятно моё повествование, пишите на почту или в комментарии к заметке, постараюсь всё объяснить!

четверг, 25 февраля 2010 г.

Scrum board плагин для mantis bug tracker

Понадобился нам скрамбоард, поискал я значит этого зверя и нашёл будет так говорить идею прикрутить скрамбоард к mantis здесь. Покопал, оказалось немного нам не подходит... Переделал...

Функционал и как работает опишу чуть позже, а сейчас пока для жаждущих выложу мануал по развёртке и исходники.


Для начала, в моём, случае в файл strings_russian.txt необходимо добавить строчки связанные с ссылкой на scrum board в меню mantis'а и блок переменных связанный с изменением в функционале, а именно, что спонсорство в моём случае используется как указание планируемого времени.

Затем необходимо немного изменить Ваш config_inc.php и указать переменные связанные со спонсорством - планируемым временем. Это действие, как я уже сказал, позволит использовать поле "Оплата отчёта" для указание планируемого времени.

Чтобы привести страницу с просмотром задач с планируемым временем к общему виду, а именно убрать заголовок, необходимо в файле account_sponsor_page.php закомментировать кусокчек php кода.

Дальше необходимо скачать архив с файлами которые были изменены здесь или послать запрос сюда и я Вам вышлю всё необходимое, и изменить конфигурацию Вашего mantis'а. Сразу уточню, что файлы в архиве содержат только так или иначе изменённые блоки...

Содержание архива:
  • board.css
  • account_sponsor_page.php
  • html_api.php
  • scrum_board.php
  • select_project.php
  • select_subproject.php
  • strings_russian.txt
Так выглядит сам scrum board


Так блок указания планируемого времени


А так ссылка в главном меню mantis'a


Так было до изменений в файле account_sponsor_page.php





А так стало после изменений, заголовка больше нет


Это выбор проекта для отображения в scrum board'е


Рабочий вариант, который при желании можно потыкать крутится здесь

Американизация русского языка и тестирование

Не могу сказать, что я ярый противник использования таких словечек как, например, "апрувить" или "тикет", но всё же тяжело воспринимаю использование этих слов другими людьми, особенно в работе. Скажу сразу, с английским дела не особо хорошо, уровень базовый - школьный.

Ну вот объясните мне люди добрые, зачем же называть задачу - тикетом, почему нельзя использовать, например, "методом свободного поиска" (с) Баранцев вместо эксплорайшн или эксплоратори?!


Я конечно понимаю и отчасти соглашаюсь с людьми, которые говорят "куда ты прёшь без инглиша в IT", но опять же, тот факт, что мы развиты меньше наших англоговорящих коллег в области того же тестирования, не значит, что мы должны превращать гидромассажную ванну в "джакузи"...

Может коряво сформулировал, писатель из меня некудышный :) но прям режет ухо когда мне говорят про всякие там тикеты в системе баг трекинга....

Кстати....
Для русского языка, напомнил президент Государственного института русского языка имени А.С.Пушкина академик Виталий Костомаров, типичны заимствования, которые мгновенно входят в систему речи. Об этом писал еще Пушкин: "Русский язык общежителен и переменчив". Однако к таким неизбежным заимствованиям следует относиться осторожно и обдуманно.
По мне, так использование чёрт бы его побрал :) тикета необдуманно ибо масса слов которые могли бы быть использованы с большей пользой.
По словам академика, сейчас же невооруженным глазом видна массовая "американизация" языка, который просто не успевает "переваривать" новые слова и выражения.
Я, кидайте же в меня камни, один из тех, кто с трудом успевает переваривать новые слова и выражения. Хотя скорей не хочет, чем не успевает.