Category: it

Category was added automatically. Read all entries about "it".

Мультибраузерные тесты

Уже не раз писал о создании тестов на селениуме, их оптимизации и различного рода хаков. После написания теста на селениуме возникает вопрос - а почему бы его не запустить на другом браузере отличном от того на котором записывал (firefox обычно или руками), запустить, посмотреть несложно,достаточно поменять лишь строку инициализации селениума в скрипте

selenium = new DefaultSelenium("localhost", SeleniumServer.getDefaultPort(), "*chrome", url);

 

например на InternetExplorer
selenium = new DefaultSelenium("localhost", SeleniumServer.getDefaultPort(), "*iexplorer", url);

 

или на оперу,сафари,
Collapse )

 

Метрики.Подробности

Не так давно я уже писал о практическом применении метрик со стороны использования программных средств для их подстчета, но вот о значении их как показателей для кода хотелось бы рассказать подробней. Итак по порядку
Collapse )

Метрики.Практическое применение.

Итак что же такое метрики и зачем они нужны. Метрики фактически являются измерением понятности,гибкости,правильности кода ну и соответственно в какой то мере качества кода, выражением его в числовом виде. Сам смысл метрик,следуя википедии, в том что необходимо числовое выражение качества кода с целью дальнейшего его увеличения. Помимо плюсов управления качеством и указания возможных рисков существуют еще и минусы метрик - иногда метриками руководствуются для выводов о профессионализме того или иного человека (что не есть правильно, метрика не оценка человека), или иногда программисты излишне уделяют им внимание (например увлекаясь их уменьшением/увеличением и забывая про основной функционал), ну и нельзя конечно всецело полагаться на метрики, ибо они тоже пишуться людьми и имеют ограниченное поле применения (не все метрики одинаково полезны!).Программных продуктов для различных метрик существует очень много взять хотя бы плагины дл Idea или Eclipse или такой консольный монстр как RSM. В общем теперь кратко о тех средствах оценки метрик, которые применяются у нас (выбор средств продиктован несколькими условиями о которых упомяну ниже).Итак список в студию -

Collapse )

Определение покрытости кода тестами

Собсна опять интересная задача - необходимо определить покрытие кода тестами, но не только юнит тестами а еще и функциональными и гуи тестами, что немного усложняет стандартные способы оценки покрытия. Покрытие кода — мера, используемая при тестировании программного обеспечения. Она показывает процент, насколько исходный код программы был протестирован.(wiki)И так более подробно - имеется веб сервлет на томкате, для которого нужно прогнать все имеющиеся юнит тесты (они гоняются во время процесса билда из анта), собрать статистику по покрытости, затем задеплойить сервлет, прогнать имеющиеся гуи тесты на селениуме, собрать статистику по покрытию, объеденить статистику и вывести в удобочитаемом виде.Сделать все желательно на опенсорсных проектах.Теперь о реализации, в качестве софта для снятия ковеража использовалась небезызвестная emma, причем не последняя stable версия а экспериментальная, почему расскажу позже.
1. Инструментим исходные классы

<emma enabled="true"> <instr destdir="output/emma" metadatafile="output/emma/metadata.emma" merge="true" instrpathref="process.classpath"> <filter value=""/> </instr> </emma>

2. Гоняем юнит тесты (дополнительные параметры необходимы для emma)
<junit fork="yes" haltonfailure="no" haltonerror="no" printsummary="yes" maxmemory="512m" forkmode="once"> <classpath refid="run.classpath.emma"/> <jvmarg value="-Demma.coverage.out.file=${basedir}/output/emma/coverage.emma"/> <jvmarg value="-Demma.coverage.out.merge=true"/> <jvmarg value="-Demma.rt.control=false"/> <jvmarg value="-Demma.coverage.out.merge=true"/> <formatter type="brief" usefile="false"/> <formatter type="xml"/> <batchtest todir="output/test-results"> <fileset dir="output/test" includes="**/*Tests.class"/> </batchtest> </junit>
3. Деплойим варку (тут думаю сложностей не будет)
<target name="deploy-war"> <deploy url="${tomcat.url}" username="${tomcat.username}" password="${tomcat.password}" path="/servicedesk" war="file:///${basedir}/output/servicedesk.war" update="true"/> </target>
4. Гоняем тесты на селениуме
<junit haltonfailure="yes" haltonerror="yes" printsummary="yes" maxmemory="512m"> <classpath refid="classpath"/> <formatter type="brief" usefile="false"/> <formatter type="xml"/> <batchtest todir="output/test-results"> <fileset dir="output/webtest" includes="**/*Tests.class"/> </batchtest> </junit>
5. Дергаем текущее состояние покрытие в реалтайме (вот в этом как раз отличие экспериментальной версии)
<emma> <ctl connect="localhost:47653"> <command name="coverage.get" args="output/emma/webcoverage.emma"/> </ctl> </emma>
6. Собираем ковераж в кучу и пишем отчет
<emma enabled="true"> <report sourcepathref="sourcePath" sort="+block,+name,+method,+class" metrics="method:70,block:80,line:80,class:100" encoding="UTF-8"> <fileset dir="output/emma"> <include name="*.emma"/> </fileset> <txt outfile="${basedir}/output/emma/coverage.txt" depth="package" columns="class,method,block,line,name"/> <xml outfile="${basedir}/output/emma/coverage.xml" depth="package"/> <html outfile="${basedir}/output/report/emma/index.html" depth="method" encoding="UTF-8" columns="name,class,method,block,line"/> </report> </emma>
собсна ничего сложного, пришлось правда малость поколдовать с настройками эммы, чтобы не было конфликтов в портах, пока разобрались как отключать.Кстати особенность экспериментальной версии в том, что можно дёргать статистику по покрытию в любое время у запущенного приложения, в нашем случае это сервлет томката, но возможно и использование в обычных jar файлах. В итоге добились примерно следующего покрытия
class - 99% (122/123) method - 97% (729/751) block - 93% (6908/7412) line - 95% (1720,3/1820)
В принципе данная статистика совсем даже не говорит о том что в проекте нет ошибок, она всего лишь показывает что покрытость кода тестами очень высока, и если качество тестов высокое, то вероятность ошибки очень мала...о качестве тестов и о тестировании тестов попробую написать в следующих статьях... ссылки по теме: emma with ant tomcat with ant junit ant task

Continious Integration + Selenium

Давно не добирался до блога вот решил написать несколько постов о том, чем занимался в это время.

В общем начну сначала - появился веб ориентированный проект на java и вместе с ним появилась необходимость тестировать и осуществлять постоянную интеграцию. В качестве сервера непрерывной интеграции был выбран Bamboo(на него же в скором времени прикрутим остальные проекты) для функционального тестирования выбрали selenium, собсна с ним и был опыт работы и данная тулза полностью удовлетворяла требованиям.

Итак что имеем:

  1. Тесты написанные на Selenium
  2. Веб приложение (servlet для tomcat)
  3. Continious integration server

Что требуется : заставить работать это все в одной связке

Решение:

У селениума как оказалось много способов интеграции с CI: питон скрипты,руби скрипты,selenese ant task, формат nuinit , формат junit. Естественно в первую очередь приходит на ум использовать именно тот формат, который ориентирован на интеграцию - selenese ant task выглядит он следующим образом

<taskdef resource="selenium-ant.properties">
    <classpath>
        <pathelement location="selenium-server.jar"/>
    </classpath>
</taskdef>
<selenese 
    suite="c:\absolute\path\to\my\HTMLSuite.html"
    browser="*firefox"
    results="c:\absolute\path\to\my\results.html"
    multiWindow="true"
    timeoutInSeconds="900"
    startURL="http://www.google.com" />

в данном скрипте указываем местонахождение селениум сервера, testcase, файл выходных результатов, время таймаута и стартовый урл. В принципе все удобно и просто - записываем плагином для файрфокса скрипт, сохраняем его в репозиторий, прописываем в TestCase и запускаем интеграцию (или запускается автоматически по коммиту), смотрим отчет в файле вывода. Все бы хорошо, но появились следующие проблемы 1) сложно интегрировать отчетность с отчетностью сервера интеграции (bamboo конечно поддерживает артифакты, но не настолько наглядно) 2) все тесты в тест кейсе получаются связанными (тут уж специфика проекта). Поэтому остановились на следующем варианте: экспорт скриптов селениума в формат junit и соответсвенно вся интеграция проходит аналогично с обычными junit тестами. После экспорта код выглядит следующим образом:

Public class WebTests {
private Selenium selenium;
@Before
public void setUp() throws Exception {
String url = http://XX:8181
selenium = new DefaultSelenium("localhost", SeleniumServer.getDefaultPort(), "*chrome", url);
selenium.start();
}

@After
public void tearDown() throws Exception {
selenium.stop();
}

@Test
public void unlinkedTest1() throws SQLException {
selenium.setSpeed("500");
loginAs("admin", "admin");
selenium.open("http://XX:8181/XXXXXXX/admin/downloadFileEmployee.html?id=100");
selenium.waitForPageToLoad("30000");

Собсна получился простой и понятный код, который позволяет внедрять дополнительную логику в тесты, применять рандомные тестовые данные, естественно в класспасе проекта должен быть селениум сервер и библиотека junit а также должен быть запущен сервер селениума, причем запущен он может на совершенно другой машине или машинах. В build.xml для анта код запуска выглядит следующим образом

<target name="selenium">
<junit haltonfailure="yes" haltonerror="yes" printsummary="yes" maxmemory="512m">
<classpath refid="classpath"/>
<formatter type="brief" usefile="false"/>
<formatter type="xml"/>
<batchtest todir="output/test-results">
<fileset dir="output/webtest" includes="**/*Tests.class"/>
</batchtest>
</junit>
</target>

т.е запускаем его как обычный junit тест (естественно после компиляции). В результате получились наглядные и удобные отчеты (это уже заслуга Bamboo - он их рисует а еще и ведет хистори и статистику) а также данный способ позволил внедрить в тесты логику, например в нашем случае это в каджом тесте перед запуском поднимается тестовое окружение (в базу инжектятся нужные данные) что позволило ускорить время выполнения тестов и убрать излишнюю связанность. В следующих постах постараюсь рассказать о Coverage статистике и определении покрытости кода функциональными тестами...