Автоматизація тестування. Початок шляху

Добрий день, Хабр!
Це мій перший пост, у цьому зв'язку прошу строго не судити, але критика вітається.
 
Темою сьогоднішньої статті буде автоматизація функціонального тестування веб-додатків. Точніше кажучи, не сама автоматизація, як вид тестування, а швидкий старт у цьому, безумовно, захоплюючій справі.
Багато тестери, що займаються проведенням функціонального і регресивного тестування, рано чи пізно приходять до думки про автоматизацію процесу, тому абсолютно точно можна сказати, що виконання одних і тих же регресійних кейсів з часом жахливо набридає.
Стаття розрахована на людей, які тільки-тільки підходять до цієї думки і не знають думають, з чого б їм почати свій шлях в автоматизації.
 
Якщо згадати себе на початку цього шляху, то виходять такі вихідні дані (готовий посперечатися, що я не самотній):
 
     
  • Є бажання автоматизувати, є проект, який можна автоматизувати;
  •  
  • Більше 50 відкритих вкладок в браузері з інформацією про автоматизацію, selenium'е, побудові фреймворків і т.д.;
  •  
  • Кілька розпочатих проектів Visual Studio, які вже закинуті в результаті тупика і усвідомлення невірного підходу;
  •  
  • Відсутність часу, офіційно виділеного керівництвом на автоматизацію, т.к. немає досвіду, невідомо що вийде (і чи вийде).
  •  
Керівництво — окрема тема.
Не можна просто так взяти і сказати: «Хочу автоматизувати!» І в підсумку отримати схвалення і час на виконання завдання. Керівництву потрібен результат, тому з їхнього боку дуже резонно не виділяти часу «не відомо на що».
 
Звідси випливають 2 ситуації:
 
Ситуація 1.
  
     
  • Крок 1. Тестіровшік озвучив ідею автоматизації, можливо навіть підготував ТЗ і справив оцінку трудовитрат і окупності.
  •  
  • Крок 2. Керівництво сказало: «Ок, дружище, приступай. До закінчення терміну потрібно надати звіт про виконану роботу ».
  •  
 Далі починається розробка, проби і помилки, нові знання, тестер мотивувати до межі. Але ось підходить термін, 90% ймовірності були труднощі при розробці (ми ж новачки, так), через які поїхали терміни, були нові ідеї, які не враховувалися в ТЗ, але реалізувати ой як хочеться. У підсумку швидше за все вийде так, що система не буде здана в строк, керівництво засмутиться (і не важливо що ми багато добилися, що ми дізналися багато нового, що ми стали більш компетентні), результату немає.
 
 Обмовлюся. Ймовірно, дорогий читачу проходив цим шляхом і все вийшло, але впевнений, таких людей меншість.
 
Ситуація 2.
  
     
  • Крок 1. Тестувальник нишком у вільний від роботи час почав вивчати тему, читати статті, трохи автоматизувати.
  •  
  • Крок 2. Проходить якийсь час і тестувальник вже має більш менш робочий проект автоматизації, кілька десятків авто-тестів. Проект ще не завершений, так, але саме час повідомити керівництву про свою ініціативу і свої успіхи, це підніме вам ціну і додасть додаткову мотивацію.
  •  
  • Крок 3. Тестувальник повідомляє керівництву, показує робочий, хай і не завершений проект, в результаті отримує схвалення і час на завершення розпочатого.
  •  
На мій погляд тут переважніше шлях 2 (ймовірно мені так здається, тому що я сам йшов саме по цьому шляху), тому що він гарантує відсутність негативного результату, адже якщо у вас раптом не вийде, ніхто не дізнається про це.
 
Розміщуючи цю статтю, я переслідую кілька цілей:
 
     
  1. Принести користь починаючому тестувальника — автоматизаторів, допомогти швидко створити перший авто-тест і продовжити автоматизувати;
  2.  
  3. Отримати критику за проектом, тому що він ще допілівать і наповнюється;
  4.  
  5. Знайти людей, які будуть використовувати систему, отримувати від них зворотний зв'язок про те, який функціонал вони б хотіли бачити з того, що ні.
  6.  
Сподіваюся, що стаття принесе користь починаючому автоматизаторів.
Також я сподіваюся на критику, тому що прикладений проект в даний момент розробляється і потребує доповнення.
 
Що використовується:
 
     
  • Мова і середовище розробки: C # в MS Visual Studio 2012 (проект class library).
  •  
  • Управління браузером: Selenium Webdriver.
  •  
  • Фреймворк тестування: NUnit.
  •  
  • Для роботи з БД (нам адже потрібно звідкись брати тестові дані, вірно?) на даному етапі використовуються стандартні
    OracleClient 
    і
    SqlClient
    ;
  •  
 Встановлення програм та настройка проекту
 
Для роботи потрібно:
 Щоб закачати проект з репозиторію, необхідно в папці (де ви хочете його утримувати) відкрити git bash і виконати команду:
 
 
git clone git://github.com/4gott3n/AT.git master 

 
Ознайомитися з роботою Git можна, наприклад, в цієї статті.
 
Далі відкриваємо файл
AT.sln
в Visual Studio і бачимо перед собою Solution, що містить проект AT (власне сам фреймворк), а також приклад тестового проекту, в якому можна побачити реалізацію сторінок, тестів і т.д. (Він є зручним прикладом для створення свого проекту).
 
Наступний крок — створення проекту, який буде зберігати всі ваші тести, сторінки і все інше.
 
Що потрібно зробити:
 
     
  1. Додати в Solution новий проект (Class library) це назва пізніше потрібно прописати в App.config;
  2.  
  3. Підключити посилання;
    У результаті повинно бути як на картинці:
     
  4.  
  5. Створити файл конфігурації App.config;
     
    У цьому файлі будуть міститися всі основні параметри проекту.
     Детальніше. App.config
    <add key="project_name" value="SampleTestProject"/>  <!-- название вашего проекта -->
     
    <!-- блок настроек для рассылки отчета о запуске тестов -->
        
    <add key="smtp_server" value="адрес smtp сервера" />
    <add key="smtp_port" value="порт" />
    <add key="smtp_login" value="логин" />
    <add key="smtp_password" value="пароль" />
    <add key="mail_from" value="ваш email" />
    <add key="mail_to" value="список рассылки через запятую" />
        
    <!-- end notif config -->  
    <!-- блок настроек браузера -->
        
    <add key="ImplicitlyWait" value="время ожидания элемента (в секундах)" />
    <add key="WaitForAjax" value="время ожидания выполнения ajax (в секундах)" />
    <add key="browser" value="текущий браузер (firefox, chrome или iexplore)" />
    <add key="browser_check_url" value="http://ya.ru" /> <!-- страница для проверка работы браузера -->
        
    <!--  browser config end  -->
    <!-- настройки страниц (webpages) -->
    
    <add key="Yandex" value="http://yandex.ru/" /> <!-- соответствие названия папки внутри WebPages главной странице тестируемой системы (в данном случае внутри папки WebPages должна быть папка Yandex) -->
    
    <add key="dash_prefix" value="___" />
    <!-- обозначение тире в названии namespace  (три нижних слеша)  -->
    
    <add key="extension_prefix" value="__" /> <-- префикс перед расширением файлов страниц (два нижних слеша), к примеру страница index-1.html должна иметь название класса index___1__html -->  
    
    <add key="folder_index_prefix" value="_fld" />
    <!-- открыть папку без имени файла страницы, это если нам нужно открыть папку, не указывая названия файла, например страница https://yandex.ru/test/, в этом случае в папке Yandex должна быть папка test, а в ней класс _fld  -->
    
    <!-- pages config end-->
    <!-- блок настроек базы данных -->
        
    <add key="database_name_prefix" value="db_" /> <!-- префикс строк конфига, содержащих строки инициализации БД-->
    <add key="database_selected_rows_limit" value="50" /> <!-- ограничение на выборку (кол-во строк) -->
        
    <add key="db_test" value="172.18.XX.XX;1521;SID;LOGIN;PASSWORD;oracle" /> <!-- пример строки инициализации БД -->
    
    <!-- формат: host;port;sid;login;password;type  (type может быть либо oracle, либо mssql-->
    
    <!-- data base config end -->
                
    <add key="test_step_prefix" value="step_" /> <!--  префикс в названиях методов для шагов тест-кейса, к примеру step_01   -->
    <add key="test_case_prefix" value="test_" /> <!-- префикс в названиях классов тест-кейсов, к примеру test_000001 -->
        
    <add key="datetime_string_format" value="yyyy-MMM-dd -> hh:mm:ss" /> <!-- формат даты для логирования -->
    <add key="log_file_name" value="system.log" /> <--! название файла для логов -->    
    

     
     
  6.  
  7. Створити папку для сторінок (WebPages).
     
    У цій папці будуть знаходитися файли з класами сторінок.
     Детальніше. WebPages. Кілька правил:
     
       
    • Папка зі сторінками повинна називатися WebPages;
    •  
    • Вона повинна знаходитися в корені проекту;

    •  
    • Всередині неї повинні міститися кореневі папки ваших тестованих системи (наприклад якщо ви тестируете Яндекс, то в папці WebPages повинна бути папка yandex);
    •  
    • Сторінки в папках повинні знаходитися в теж же ієрархії, як вони знаходяться в тестованої системі;
       Приклад:
      Сторінка: test.ru/step1/service/index.html
      Ієрархія папок: WebPages -> Test -> step1 -> service -> index.html.cs
       Важливо: імена папок і класів чутливі до регістру
    •  
    • Назви файлів класів сторінок повинні відповідати реальним іменам сторінок
    •  
    Назви класів сторінок:
     Приклад:
    Сторінка: index-1.html
    Клас: index___1__html
    Тут:
     
       
    • Дефіс в назві сторінки замінюється трьома слешів (можна змінити, параметр dash_prefix в App.config);
    •  
    • Точка файлу замінюється двома слешів (можна змінити, параметр extension_prefix в App.config;
    •  
    Назви класів, коли немає назви файлу, а є тільки папка:
     Приклад:
    Сторінка: test.ru/step1/service /
    Клас: _fld (можна змінити, параметр folder_index_prefix в App.config)
     
     
  8.  
  9. Створити клас Pages.cs
     
     
    public static class Pages {  }
    

    Клас міститиме об'єкти класів сторінок (WebPages);
     Детальніше. Pages.cs Цей клас містить об'єкти класів сторінок, через які здійснюється доступ до елементів і т.д.
     
     Кілька правил:
     
       
    • У цьому класі ієрархія підкласів повинна збігатися з ієрархією в папці WebPages;
    •  
    • Клас і всі об'єкти всередині нього повинні бути public static.
    •  
     Приклад класу:
     
    public static class Pages
    {
            public static class Test
            {
                    public static index__html Index = new index__html();
                    public static class step1
                    {
                             public static class service
                             {
                                     public static _fld Main = new _ fld();
                             }
                             public static add__php Add = new add__php();
                     }
              }
        }
    

     
    При такого запису сторінки будуть доступні в тестах приблизно так:
     
     
    Pages.Test.Index.Open();
    Pages.Test.step1.service.Main.Open();
    

     
     
  10.  
  11. Створити папку для тестів (Tests)
     
    Тут немає особливих правил, досить створити в корені проекту папку Tests, всередині неї створити папки з тестами по тестируемим системам так, як душі завгодно.
     Детальніше. Tests На картинці зображено як це зроблено у мене на проекті:
     
     
    Дуже доречним буде створити два «службових» тесту, які завжди будуть запускатися першим і останнім. У першому тесті можна виконувати різні дії з налаштування середовища, в останньому, наприклад, виконувати очищення стенду і запускати нотифікацію.
     Nunit запускає тести всередині категорії в алфавітному порядку (по повній назві класів)
     
    Для запуску нотифікації необхідно виконати код:
     
    AT.Service.Notifier.SendNotif();
    

    Також не зайвим буде створити клас Environment.cs
     
    public static class Environment {  }
    

    Особисто я використовую його для зберігання різних глобальних змінних і констант.
     
  12.  
 Приклад створення сторінки (WebPages)
 
Всі створювані сторінки успадковуються від базового класу
PageBase
, який містить необхідні методи, однакові для всіх сторінок: «відкрити», «відкрити з параметром», «отримати Url».
 
 Приклад класу сторінки:
 
public class index__php : PageBase
    {        
        public void OpenVpdnTab()
        {
            new WebElement().ByXPath("//a[contains(@href, '#internet')]").Click();
        }
        public string VpdnAction
        {
            get { return new WebElementSelect().ByXPath("//select[@name='action']").GetSelectedValue(); }
            set { new WebElementSelect().ByXPath("//select[@name='action']").SelectByValue(value); }
        }
        public string VpdnLid
        {
            set { new WebElement().ByXPath("//input[@name='lid']").SendKeys(value); }
        }
        public string VpdnTechlist
        {
            set { new WebElement().ByXPath("//input[@name='file']").SendKeys(value); }
        }
        public string VpdnStartDate
        {
            set { new WebElement().ByXPath("//input[@name='start_date']").SendKeys(value); }
        }
        public void VpdnSubmit()
        {
            new WebElement().ByXPath("//input[@value='Применить']").Click();
        }
}

 Правило:
Всі елементи, які присутні на сторінці, повинні инициализироваться в момент звернення до них.
 
 Приклади роботи зі сторінками:
 
Pages.Test.Index.Open();
— відкрити
 
Pages.Test.Index.Open(“?id=1”);
— відкрити з параметром
 
var url = Pages.Test.Index.Url;
— отримання адреси сторінки
 
Pages.Test.Index.VpdnSubmit(); 
— запуск функції, прописаної в класі сторінки вище
 
 Приклад створення тест-кейсу (Test)
 
Як вже зазначалося вище, все тест-кейси повинні лежати в папці
Tests
.
Всі тест-кейси повинні бути public і успадковуватися від базового класу
TestBase
.
 
Перед назвою класу з тест-кейсом повинен бути вказаний атрибут
[TestFixture]
.
Перед кожним кроком тест-кейсу повинен бути вказаний атрибут
[Test]
.
 
Детальніше про атрибути тестів можна почитати тут .
 
 Приклад класу з тест-кейсом:
 
 
namespace TestProject.Tests.OSE
{
    [TestFixture]
    [Category("OSE"), Category("OSE_Internet")] /* категории, nunit позволяет запускать тесты выборочно по категориям */
    public class test_253750 : TestBase
    {
        [Test]
        public void step_01()
        {
            Pages.OSE.Inaclogin.Open();
            Pages.OSE.Inaclogin.Login = “user”;
            Pages.OSE.Inaclogin.Password = “password”;
            Pages.OSE.Inaclogin.Submit();

             Assertion("Ошибка авторизации”, () => Assert.AreEqual(Pages.OSE.Inaclogin.IsAuthSuccess, true));
        }
}

 
 
Assertion
— це перевірка виконання умови.
 
Формат запису:
 
Assertion (текст ошибки, () => Assert.любой_accert_из_nunit() );  

 
Чому не використовуємо просто Assert?
Всі Assert'и відловлюються спеціальним класом, в якому виконуються дії з реєстрації помилок, логування і т.д.
 
 Приклади роботи з БД
 
Для роботи з БД використовується клас
AT.DataBase.Executor
, що містить методи:
 
     
  • Виконання запитів на вибірку (select);
  •  
  • Виконання запитів типу insert, update, delete (unselect);
  •  
  • Виконання збережених процедур.
  •  
 Приклади:
 
Select:
 
var query = select col1, col2 from table_name";
var list = Executor.ExecuteSelect(query, Environment.Имя_БД);

Unselect:
 
var query = “DELETE FROM table_name"; 
Executor.ExecuteUnSelect(query, Environment.Имя_БД);

Виконання збереженої процедури:
 
Executor.ProcedureParamList.Add(new ProcedureParam("varchar", "имя_параметра", «значение»)); /* входной параметр */
Executor.ProcedureParamList.Add(new ProcedureParam("varchar")); /* возвращаемое значение */
var res = Executor.ExecuteProcedure("имя_процедуры", Environment.Имя_БД); 

 
имя_БД
повинно відповідати значенню sid з рядка ініціалізації БД в App.config
 
<add key="db_test" value="172.18.XX.XX;1521;SID;LOGIN;PASSWORD;oracle" /> <! -- пример строки инициализации БД -->

 
 Збір результатів тестування і приклад звіту:
 
Як вже згадувалося вище, для запуску нотифікації і отримання звіту на пошту необхідно після запуску останнього тесту виконати код
AT.Service.Notifier.SendNotif();

Логіка NUnit така, що він запускає тести в алфавітному порядку, відповідно щоб потрібний тест запустився останнім, його потрібно назвати відповідним чином.
 
Налаштування сповіщення вказуються у файлі App.config.
 
 Приклад звіту (він ще сируватий, мало інформації):
 
 Autotest Report
       
000001 Failed step_01: error
 Слід. крок: Крок не виконувався, помилка на попередньому кроці
 Слід. крок: Крок не виконувався, помилка на попередньому кроці
 Слід. крок: Крок не виконувався, помилка на попередньому кроці
 
 Summary :
Pass Rate = 0%.
 
Виконавши всі пункти цієї міні-інструкції юний тестувальник — Автоматор зможе в короткі терміни створити свій проект і отримати той мінімум, який необхідний для початку цього шляху.
 
 Підведення підсумків.
Варто відзначити, що пропонована система ще остаточно не дороблена, є ще багато ідей, які будуть реалізовані (дуже сподіваюся на пропозиції щодо поліпшення від дорогого читача).
Якщо буде інтерес, в наступних статтях я детально опишу роботу фреймворка, настройку і запуск тестів.
Насчет запуску тестів скажу лише, що я в роботі використовую безкоштовний teamcity , він, на мій погляд, дуже зручний і простий в освоєнні.
 
Сподіваюся, що прочитання цього поста виявилося для кого-небудь корисним.
Спасибі за увагу.

Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.