понедельник, 16 декабря 2013 г.

Тестирование верстки 2

Тестирование с помощью fighting layout bugs

Я думаю не многие знают про гугловую open-source либу,для тестирования верстки и различных layouts,а она совсепм даже не плоха.
Взять ее можно вот тут.
Если кратко,что она умеет?
Находит битые ссылки:
  • Сканирует  HTML теги <img> и проверяет src атрибуты.
  • Сканирует CSS  вск атрибуты style и <style> елементы в HTML и все указанные URL в них.
  • Проверяет фавиконки по урлам.
Проверяет необходимый горизонтальный скроллинг

 Можно указать минимально поддерживаемое разрешение экрана для вашей веб страницы
примерно так:


 
FightingLayoutBugs flb = new FightingLayoutBugs(); flb.configure(DetectNeedsHorizontalScrolling.class).setMinimalSupportedScreenResolution(800, 600);

По умолчанию минимальное разрешение 1024 x 768.

  • Так же проверяет текст на слишком маленький контраст.
  • Распознает текст, который очень близко или перекрывает горизонтальный край
  • Распознает текст, который очень близко или перекрывает вертикальный край
И собственно прикрутить,ее очень просто

 
    FirefoxDriver driver = new FirefoxDriver();
    try {
        String testPageUrl = "http://www.test.de/";
        driver.get(testPageUrl);
        WebPage webPage = new WebPage(driver);
        FightingLayoutBugs flb = new FightingLayoutBugs();
        final Collection layoutBugs = flb.findLayoutBugsIn(webPage);
        System.out.println("Found " + layoutBugs.size() + " layout bug(s).");
        for (LayoutBug bug : layoutBugs) {
            System.out.println(bug);
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        driver.quit();
    }


 В общем я думаю стоит попробовать.

четверг, 5 декабря 2013 г.

Тестирование верстки

Тестирование верстки

В общем то идея далеко не новая,как быстро и автоматизированно следить за тем,чтобы при новом билде не расползлась верстка в разных браузерах.
Браузеров много,проект большой,мануальные тестировщики все не успеют.
Попробуем автоматизировать.
Для этого подойдет Selenium WD(т.к. у него поддержка кучи браузеров и снятие скриншотов,то которое нам нужно) и всего навсего средства Java чтобы следить за соответствием скринов.
Не буду говорить, как именно нужно снимать и проверять скриншоты,но мне кажется удобно или сделать пачку "эталонных скринов" и новые сравнивать с ними,или лезть на боевой сервер,делать скрин оттуда,а после снимать скрин на qa-стенде.
Второй вариант дольше,но надежнее в плане не устаревани "эталонных скриншотов".
В общем хватит об этом,как это сделать?
Примерно так:
Через WD  снять скрин можно так:

 
   public void makeScreenshot(String methodName) {
        try {
            File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
            FileUtils.copyFile(scrFile, new File("target" + File.separator + "failure_screenshots" +
                    File.separator + methodName+".png"));
        } catch (IOException e1) {
            e1.printStackTrace();
        }
    } 
Конечно это не единственный способ для снятия скриншотов,но сойдет.
Вроде есть много java-библиотек для работы с изображениями,но стоящую и для такой не трудной задачи искать действительно тяжело.(я вроде как не нашел)
в общем можно использовать этот класс:


import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * I am gonna pass two images and I am gonna recort only the differences
 * trying to catch if there is a different object or not int the scene
 *
 * @author maikon
 */
public class CheckingDifferentImages {

    public static void checkDifference(String pathToTheFirstScreen, String pathToTheSecond, String nameDifference) {
        BufferedImage im1 = null;
        BufferedImage im2 = null;
        try {
            //loading the two pictures
            //read and load the image
            BufferedImage input = ImageIO.read(new File("target"+File.separator+"failure_screenshots"+File.separator+pathToTheFirstScreen));
            //build an image with the same dimension of the file read
            im1 =
                    new BufferedImage(input.getWidth(), input.getHeight(), BufferedImage.TYPE_INT_ARGB);
            //object create to draw into the bufferedImage
            Graphics2D g2d = im1.createGraphics();
            //draw input into im
            g2d.drawImage(input, 0, 0, null);
            //making all again for the second image

            BufferedImage input2 = ImageIO.read(new File("target"+File.separator+"failure_screenshots"+File.separator+pathToTheSecond));
            //build an image with the same dimension of the file read
            im2 =
                    new BufferedImage(input2.getWidth(), input2.getHeight(), BufferedImage.TYPE_INT_ARGB);
            //object create to draw into the bufferedImage
            Graphics2D g2d2 = im2.createGraphics();
            //draw input into im
            g2d2.drawImage(input2, 0, 0, null);
        } catch (IOException ex) {
            Logger.getLogger(CheckingDifferentImages.class.getName()).log(Level.SEVERE, null, ex);
        }

        showDifference(im1, im2, nameDifference);

    }

    public static void showDifference(BufferedImage im1, BufferedImage im2, String nameDifference) {
        BufferedImage resultImage =
                new BufferedImage(im1.getWidth(), im2.getHeight(), BufferedImage.TYPE_INT_ARGB);

        double THR = 50;
        int area = 0;
        for (int h = 0; h < im1.getHeight(); h++) {
            for (int w = 0; w < im1.getWidth(); w++) {

                int red1 = 0xff & (im1.getRGB(w, h) >> 16);
                int green1 = 0xff & (im1.getRGB(w, h) >> 8);
                int blue1 = 0xff & im1.getRGB(w, h);


                int red2 = 0xff & (im2.getRGB(w, h) >> 16);
                int green2 = 0xff & (im2.getRGB(w, h) >> 8);
                int blue2 = 0xff & im2.getRGB(w, h);

                //euclidian distance to estimate the simil.
                double dist = 0;
                dist = Math.sqrt(Math.pow((double) (red1 - red2), 2.0)
                        + Math.pow((double) (green1 - green2), 2.0)
                        + Math.pow((double) (blue1 - blue2), 2.0));
                if (dist > THR) {
                    resultImage.setRGB(w, h, im2.getRGB(w, h));
                    area++;
                } else {
                    resultImage.setRGB(w, h, 0);
                }
           //2nd option
           /*     if (dist > THR) {
                    resultImage.setRGB(w, h,255);
                    area++;
                } else {
                    resultImage.setRGB(w, h, im1.getRGB(w, h));
                }*/
            } //w
        } //h
        try {
            File fileScreenshot = new File("target" + File.separator + "DifferenceScreens" + File.separator + nameDifference);
            fileScreenshot.getParentFile().mkdirs();
            ImageIO.write(resultImage, "PNG", fileScreenshot);
        } catch (IOException ex) {
            Logger.getLogger(CheckingDifferentImages.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    //end functionn

}

Попробуем что нить простое(не придираться,это для примера)

 
  @Test
    public void testYandex(){
        get("http://www.yandex.ru/");
        makeScreenshot("1");
        get("http://www.yandex.ru/");
        makeScreenshot("2");
        CheckingDifferentImages.checkDifference("1.png","2.png","diff.png");
    }

В результате:
1й скрин
2й скрин
и отличие(если вы заметили то в классе 2 варианта,один закомменитрован) так что:
и 2м способом

Вот и все.

среда, 4 декабря 2013 г.

Security Regression Tests

 Тестированиe безопасности в регрессе

В общем у многих есть регресс сьюты,но мало у кого есть какое-либо тестирование безопасности,я попробую рассказать ,как его можно добавить без особых затрат.
И так,подразумеваем,что у нас есть рабочий регресс который покрывает большую(а лучше полную) часть нашего функционала веб-приложения.
Значит нужно к нему привязать хороший сканер уязвимостей,который поможет находить проблемы на более ранних стадиях разработки.
Советую обратить внимание на инструмент OWASP ZAP, потому что он (как мне кажется) полностью удовлетворяет нашим требованиям.(ну и + OWASP классная команда с активным комьюнити и все такое)
В общем  для начала о нем,что он из себя представляет.Можно погуглить и посмотреть на эти слайды:



А теперь как это работает у меня

Есть сборщик Maven который собирает и запускает наши тесты, и поднимает тулзу Owasp ZAP,которая поднимает свой прокси который я ему задал.
Затем,мы поднимаем браузер с настроенным прокси(указываем прокси ZAP),в котором будут выполняться тесты.
Это позволит нам видеть все запросы и ответы производимые тестами и так же позволит нам отслеживать и проверять все AJAX запросы (которые не всегда могут быть протестированы).
ZAP пассивно просматривает все ответы от веб-приложения и проводит проверку по заданным "рулам".
Пассивное сканирование не изменяет ответы и запросы и следовательно безопасно в использовании на любых площадках.
Сканирование выполняется в фоновом потоке, что исключает снижение скорости работы приложения.

После прогона всего сьюта можно пробежаться пауком по заданному узлу,чтобы найти то,что не прошло через наше прокси.
После чего запускаем активное скнирование
Активное сканирование пытается найти потенциальные уязвимости с использованием известных OWASP аттак.(а их совсем не мало)
Не желательно использовать такой вид тестирования на боевом сервере.
Естественно, активное сканирование находит только определенные виды уязвимостией,логические уязвимости,как контроль доступа, проверены быть не могут и должны проверятся мануальным тестированием.
И да,проводится также проверка на CSRF форм (это проверка на сабмит форм со случайным параметром, используемых для защиты от CSRF атак.)

Вот и все,всем спасибо.