Otomatisasi dengan Codeception + Gherkin + PageObject untuk yang terkecil


Karena tidak menemukan satu contoh konkret dari implementasi Gherkin dengan pola desain Objek Halaman untuk Codeception di Internet , saya berpikir bahwa tidak akan salah tempat untuk memberi tahu Internet tentang implementasi pola ini oleh kami sendiri.

Artikel ini lebih ditujukan bagi mereka yang sudah sedikit terbiasa dengan Codeception atau kerangka kerja serupa, tetapi belum tahu cara menggunakan Objek Tes untuk membuat tes lebih mudah dibaca, menyederhanakan dukungan mereka dan mengurangi jumlah kode tambahan. Namun demikian, saya mencoba menjelaskan langkah-langkah utama dalam merakit proyek otomatisasi dari awal.

Template Objek Halaman memungkinkan Anda untuk merangkum pekerjaan dengan elemen halaman, yang pada gilirannya memungkinkan Anda untuk mengurangi jumlah kode dan menyederhanakan dukungannya. Semua perubahan di UI mudah dan cepat diimplementasikan - cukup perbarui kelas Objek Halaman yang menjelaskan halaman ini. Keuntungan penting lain dari pendekatan arsitektur ini adalah memungkinkan Anda untuk tidak mengacaukan skrip pengujian HTML dengan detail, yang membuatnya lebih mudah dimengerti dan mudah dipahami.

Ini adalah bagaimana tes terlihat tanpa menggunakan Obyek Halaman



Menggunakan Objek Halaman



Saya tidak akan berkutat untuk menginstal lingkungan dasar, saya akan memberikan data awal saya:

  • Ubuntu bionic beaver
  • PHP 7.1.19-1
  • Komposer - manajer manajemen ketergantungan untuk PHP, diinstal secara global
  • PhpStorm - lingkungan pengembangan

Untuk menjalankan tes, kita juga perlu:


Perluas Codeception


Lanjutkan untuk menginstal Codeception:

Kami membuka di terminal direktori yang kami butuhkan, di mana kami akan mengumpulkan proyek, atau membuat direktori untuk proyek dan pergi ke sana:

mkdir ProjectTutorial cd ProjectTutorial 

Instal kerangka Codeception dan dependensinya:

 composer require codeception/codeception --dev 



File instalasi dependensi composer.json dalam proyek akan terlihat seperti ini:

 { "require": { "php": ">=5.6.0 <8.0", "facebook/webdriver": ">=1.1.3 <2.0", "behat/gherkin": "^4.4.0", "codeception/phpunit-wrapper": "^6.0.9|^7.0.6" }, "require-dev": { "codeception/codeception": "^2.5", "codeception/base": "^2.5" } } 

Perluas proyek:

 php vendor/bin/codecept bootstrap 



Informasi lebih lanjut tentang cara menginstal proyek dapat ditemukan di dokumentasi resmi .

Pada tahap ini, tiga set tes dibuat di proyek kami. Secara default, Codeception membaginya menjadi penerimaan, fungsional, dan unit. Untuk set ini, Codeception juga menghasilkan tiga file yml. Di dalamnya kami menunjukkan semua konfigurasi yang diperlukan, sambungkan modul dan properti untuk menjalankan pengujian kami.

Pelajaran ini dibangun di atas contoh tes Penerimaan, jadi saya akan memberikan pengaturan di Acceptance.suite.yml.

Buka proyek kami di PHP Storm (atau lingkungan pengembangan favorit lainnya) dan pergi ke Acceptance.suite.yml (secara default, itu terletak di folder tes / accept.suite.yml).
Kami menuliskan dependensi minimum yang diperlukan dan selalu memperhatikan pemformatan. Modul dipisahkan oleh tanda "-" dan harus berada pada level yang sama, jika tidak kesalahan akan memercik saat tes dimulai.

Ternyata:

 actor: AcceptanceTester modules: enabled: - WebDriver: url: 'http://yandex.ru/' //    ,        browser: 'chrome' - \Helper\Acceptance //          gherkin: contexts: default: - AcceptanceTester 

Dan beberapa pekerjaan persiapan:

Buat direktori terpisah di root proyek (I have lib).
Dalam direktori ini, buat file executable run.sh, yang akan menjalankan Selenium dan Driver Chrome.

Kami menempatkan Selenium dan Driver Chrome di sini, dan menulis perintah run di run.sh:

 java -jar -Dwebdriver.chrome.driver=chromedriver_241 selenium-server-standalone-3.14.0.jar 

Bagaimana kelihatannya dalam proyek:



Kami kembali ke konsol dan mengubah hak akses:

 chmod +x ./run.sh 

(catatan. Nama-nama driver yang terletak di direktori harus sama persis dengan yang ditentukan dalam perintah mulai).

Anda dapat memulai Selenium dan Webdriver sekarang agar tidak kembali ke ini. Untuk melakukan ini, buka tab terminal baru, pergi ke direktori di mana file run.sh terletak dan tulis perintah peluncuran:

 ~/AutomationProjects/ProjectTutorial/lib$ ./run.sh 

Pastikan server berjalan:



Kami membiarkannya dalam kondisi berjalan. Pada pekerjaan persiapan ini selesai.

Menulis skrip uji


Kami terus membuat file fitur untuk kasus uji kami. Untuk melakukan ini, perintah khusus disediakan di Codeception, jalankan di konsol:

 cept g:feature acceptance check 

(perhatikan "periksa" - nama tes saya)

Kami melihat file check.feature baru di folder penerimaan.



Kami tidak memerlukan konten default, kami segera menghapusnya dan menulis pengujian kami.

Agar kolektor mengenali alfabet Cyrillic, jangan lupa untuk memulai skrip dengan #language: ru.
Kami sedang menulis naskah pendek dalam bahasa Rusia. Saya mengingatkan Anda bahwa setiap kalimat harus dimulai dengan kata kunci: "Kapan", "Lalu", "Dan", simbol "*", dll.

Sebagai contoh saya, saya mengambil situs web Yandex, Anda dapat mengambilnya.



Untuk melihat langkah-langkah apa yang ada dalam pengujian, kami menjalankan skrip kami di terminal:

 cept dry-run acceptance check.feature 



Langkah-langkah skrip ditampilkan di konsol, tetapi implementasinya belum tersedia.

Kemudian kami menjalankan perintah yang secara otomatis akan menghasilkan template untuk menerapkan metode kami:

 cept gherkin:snippets acceptance 



Semua nama dari skrip yang ada dalam tanda kutip diganti dengan variabel: arg.
Kami menyalinnya dari terminal dan menempelkannya ke file AcceptanceTester.php , tempat metode untuk bekerja dengan elemen halaman akan terletak.



Ubah nama metode menjadi yang dapat dibaca, mencerminkan esensinya (opsional), dan tulis implementasinya.



Semuanya sederhana, tetapi bahkan lebih sederhana jika Anda bekerja di lingkungan pengembangan cerdas, seperti Storm, yang dengan sendirinya akan meminta perintah yang diperlukan dari perpustakaan:



Kami menghapus kelebihan dan menulis metode:

 /** * @When      */ public function step_beingOnMainPage($page) { $this->amOnPage('/'); } /** * @Then    :element */ public function step_seeElement($element) { this->seeElement($element); } /** * @Then    :button */ public function step_clickOnButton($button) { $this->click($button); } /** * @Then    :field  :text */ public function step_fillField($field, $text) { $this->fillField($field, $text); } 

Mari kita lihat apa yang terjadi. Kami meluncurkan tim yang akan menunjukkan kepada kami metode (langkah) mana yang sekarang kami implementasikan.

 cept gherkin:steps acceptance 



Sukses!

Tetapi langkah-langkah dalam file fitur masih belum dikenali sebagai metode.



Agar Storm memahami apa yang harus dilakukan dengan langkah-langkahnya, kami akan melakukan trik dengan mengimplementasikan antarmuka Konteks dari namespace Gherkin Context.

 namespace Behat\Behat\Context { interface Context {} } 

Bungkus kelas AcceptanceTester kami dalam namespace dan mewarisi dari Konteks

 implements \Behat\Behat\Context\Context 



Sekarang semua langkah file fitur terkait dengan implementasinya:



Agar Webdriver memahami apa yang harus diklik dan ke mana harus mencari, Anda perlu mengganti nama elemen dan alamat halaman yang dapat dibaca dengan locator dan URL yang sesuai, yang akan termasuk dalam metode sebagai argumen.

Kemudian kami mendapatkan tes formulir:



Dan Anda dapat menjalankan:

 cept run acceptance 



Lulus

sekitar Jika elemen halaman membutuhkan waktu lama untuk dimuat, Anda dapat menambahkan tunggu ke metode yang diinginkan:

 $this->waitForElementVisible($element); 

Kami kembali ke skenario pengujian kami. Kami kesal karena keseluruhan keterbacaan tes hilang karena fakta bahwa alih-alih nama elemen dan halaman yang jelas, kami melihat elemen dan url HTML.

Jika kita ingin memperbaikinya, saatnya beralih ke penerapan pola Obyek Halaman.

Pergi ke Halaman Obyek


Di direktori _support, buat direktori Halaman, tempat kami akan meletakkan halaman kelas kami:

 php vendor/bin/codecept generate:pageobject MainPage 

Obyek Halaman pertama adalah halaman utama Yandex, sebut saja MainPage, kita akan memanggil kelas yang sama:



Di sini kita mendeklarasikan bidang dan metode statis sehingga dapat dipanggil tanpa membuat objek.

Karena dalam konfigurasi Acceptance.suite.yml, kami telah menentukan url halaman awal: yandex.ru , untuk halaman utama cukup untuk menentukan

 public static $URL = '/'; 

Berikutnya adalah array elemen halaman. Kami menggambarkan pelacak untuk beberapa elemen dan memberi mereka nama yang jelas dan unik.

Sekarang Anda perlu menambahkan metode getElement, yang akan mengembalikan locator dengan nama elemen dari array.

Sebagai hasilnya, kami memiliki:

 <?php //location: tests/_support/Page/MainPage.php namespace Page; /**   */ class MainPage { public static $URL = '/'; public static $elements = array( ' ' => "//*[@id='wd-wrapper-_afisha']", ' ' => "//*[@data-statlog='afisha.title.link']", ' ' => "//*[@class='weather__icon weather__icon_ovc']|//*[@class='weather__icon weather__icon_skc_d']", ); public static function getElement($name){ return self::$elements[$name]; } } 

Tambahkan beberapa kelas halaman:

/ ** Poster * /



/ ** Poster - Hasil Pencarian * /



Kami kembali ke kelas AcceptanceTester.php , tempat kami menulis metode kami.
Mari kita buat di dalamnya array kelas PageObject, di mana kita akan menetapkan nama-nama ke halaman dan menunjukkan nama kelas mereka di namespace:

  private $pages = array( " " => "\Page\MainPage", "" => "\Page\AfishaPage", " -  " => "\Page\AfishaResult" ); 

Setiap PageObject baru ditambahkan dengan cara yang sama ke array ini.

Selanjutnya, kita perlu membuat bidang CurrentPage, yang akan menyimpan tautan ke PageObject halaman saat ini:

 private $currentPage; 

Sekarang kita akan menulis metode, ketika dipanggil, kita bisa mendapatkan currentPage dan menginisialisasi kelas PageObject yang kita butuhkan.

Adalah logis untuk membuat langkah seperti ini menggunakan metode "Ketika pengguna menavigasi ke halaman" Nama Halaman ". Maka cara paling sederhana untuk menginisialisasi kelas PageObject, tanpa pemeriksaan, akan terlihat seperti ini:

 /** * @When     :page */ public function step_beingOn($page) { //   pageObject $this->currentPage = $this->pages[$page]; } 

Sekarang kita menulis metode getPageElement, yang akan memungkinkan kita untuk mendapatkan elemen, atau lebih tepatnya, pelacaknya dari halaman saat ini:

 private function getPageElement($elementName) { //         $curPage = $this->currentPage; return $curPage::getElement($elementName); } 



Untuk metode yang sudah diterapkan, perlu untuk mengganti argumen yang kami terima langsung dari teks fitur di awal dengan elemen dari PageObject, yaitu:

 $arg 

akan mengambil formulir

 getPageElement($arg)) 

Kemudian metode kami akan berbentuk:

 /** * @When     :page */ public function step_beingOnMainPage($page) { //      pageObject $this->currentPage = $this->pages[$page]; $curPage = $this->currentPage; $this->amOnPage($curPage::$URL); } /** * @Then    :element */ public function step_seeElement($element) { $this->waitForElementVisible($this->getPageElement($element)); $this->seeElement($this->getPageElement($element)); } /** * @Then    :button */ public function step_clickOnButton($button) { $this->click($this->getPageElement($button)); } /** * @Then    :field  :text */ public function step_fillField($field, $text) { $this->fillField($this->getPageElement($field), $text); } /** * @Then      :field */ public function step_deleteText($field) { $this->clearField($this->getPageElement($field)); } 

Menambahkan metode lain untuk menampilkan hasil pencarian dengan menekan Enter:

 /** * @Then    ENTER */ public function step_keyboardButton() { $this->pressKey('//input',WebDriverKeys::ENTER); } 

Langkah terakhir adalah ketika semua metode dan PageObjects yang diperlukan dijelaskan, Anda perlu memperbaiki tes itu sendiri. Tambahkan langkah-langkah yang akan menginisialisasi PageObject ketika pergi ke halaman baru. Kami memiliki "* pengguna ini pergi ke halaman: halaman".

Untuk kejelasan, saya akan menambahkan beberapa langkah lagi. Hasilnya adalah tes ini:

 #language: ru :     :   .    .   .      " "     " "     " "     " "      ""     " "  " "     ENTER      " -  "     "   "       " "     " "  ""     ENTER 

Skenario pengujian seperti itu dapat dipahami dan dibaca oleh orang luar.

Luncurkan!

Untuk melihat hasil proses yang lebih rinci, Anda dapat menggunakan perintah

 cept run acceptance --debug 

Kami melihat hasilnya:



Dengan demikian, menggunakan pola Obyek Halaman memungkinkan Anda untuk memisahkan semua elemen halaman dari skrip pengujian dan menyimpannya dalam direktori yang terpisah.

Proyek itu sendiri dapat ditemukan di https://github.com/Remneva/ProjectTutorial

Sebagai seorang insinyur otomasi pemula, saya akan berterima kasih jika Anda membagikan ide-ide Anda dan, mungkin, memberi tahu saya bagaimana mengubah dan menyederhanakan struktur proyek secara lebih logis.

Source: https://habr.com/ru/post/id427031/


All Articles