A felhasználói felületi tesztek írása

Befejeződött

Ebben a szakaszban segít Andynek és Amitának szelénteszteket írni, amelyek ellenőrzik az Amita által leírt felhasználói felületi viselkedéseket.

Amita általában a Chrome, a Firefox és a Microsoft Edge rendszeren futtat teszteket. Itt is ugyanezt kell tennie. A Microsoft által üzemeltetett ügynök, amelyet használni fog, előre konfigurálva van az egyes böngészők használatához.

Az ág lehívása a GitHubról

Ebben a szakaszban lekéri az ágat a selenium GitHubról. Ezután kiveheti vagy átválthat erre az ágra. Az ág tartalma segít követni az Andy és Amita által írt teszteket.

Ez az ág tartalmazza azt a Space Game-projektet , amellyel a korábbi modulokban dolgozott. Emellett tartalmaz egy Azure Pipelines-konfigurációt is, amellyel kezdeni kell.

  1. Nyissa meg az integrált terminált a Visual Studio Code-ban.

  2. A Microsoft-adattárból elnevezett selenium ág letöltéséhez váltson erre az ágra, és futtassa a következőket git fetch és git checkout a parancsokat:

    git fetch upstream selenium
    git checkout -B selenium upstream/selenium
    

    Tipp.

    Ha követte Amita manuális tesztjét az előző leckében, előfordulhat, hogy már futtatta ezeket a parancsokat. Ha már futtatta őket az előző leckében, akkor most is futtathatja őket.

    Ne feledje, hogy a felsőbb réteg a Microsoft GitHub-adattárra hivatkozik. A projekt Git-konfigurációja megérti a távoli felsőbb réteget, mert beállította ezt a kapcsolatot. Akkor állítja be, amikor elágazott a projekt a Microsoft-adattárból, és helyileg klónozta.

    Ezt az ágat hamarosan leküldi majd a saját, origin nevű GitHub-adattárába.

  3. A Visual Studio Code-ban is megnyithatja az azure-pipelines.yml fájlt. Ismerkedjen meg a kezdeti konfigurációval.

    A konfiguráció a képzési terv korábbi moduljaiban létrehozottakhoz hasonlít. Kizárólag az alkalmazás Kiadás konfigurációját buildeli. A rövidség kedvéért kihagyja a korábbi modulokban beállított triggereket, manuális jóváhagyásokat és teszteket is.

    Megjegyzés:

    Egy robusztusabb konfiguráció megadhatja azokat az ágakat, amelyek részt vesznek a buildelési folyamatban. A kódminőség ellenőrzéséhez például minden alkalommal futtathat egységteszteket, amikor bármilyen ágon leküld egy módosítást. Az alkalmazást olyan környezetben is üzembe helyezheti, amely részletesebb tesztelést végez. Ezt az üzembe helyezést azonban csak akkor hajtja végre, ha lekéréses kérelemmel rendelkezik, ha van kiadási jelöltje, vagy amikor kódot egyesít főként.

    További információ: Kód-munkafolyamat implementálása a buildelési folyamatban a Git, a GitHub és a Build folyamat eseményindítóinak használatával.

Az egységteszt kódjának írása

Amita izgatottan tanulja meg a webböngészőt vezérlő kód írását.

Ő és Andy együtt fogják írni a szelénteszteket. Andy már beállított egy üres NUnit-projektet. A folyamat során hivatkoznak a szelén dokumentációjára, néhány online oktatóanyagra, valamint azokra a jegyzetekre, amelyeket Amita manuális tesztek során készítettek. A modul végén további erőforrásokat talál, amelyekkel végigvezetheti a folyamaton.

Tekintsük át azt a folyamatot, amelyet Andy és Amita használ a tesztek megírásához. Ezt követve megnyithatja a HomePageTest.cs fájlt a Tailspin.SpaceGame.Web.UITests könyvtárban a Visual Studio Code-ban.

A HomePageTest osztály definiálása

Andy: Az első dolog, amit meg kell tennünk, hogy meghatározzuk a tesztosztályunkat. Számos elnevezési konvenció egyikét követhetjük. Hívjuk meg az osztályt HomePageTest. Ebben az osztályban az összes, a kezdőlaphoz kapcsolódó tesztet elhelyezzük.

Andy hozzáadja ezt a kódot a HomePageTest.cs fájlhoz:

public class HomePageTest
{
}

Andy: Ezt az osztályt public úgy kell megjelölnünk, hogy elérhető legyen az NUnit-keretrendszer számára.

Az IWebDriver tagváltozó hozzáadása

Andy: Most egy tagváltozóra IWebDriver van szükségünk. IWebDriver az a programozási felület, amellyel elindíthat egy webböngészőt, és kezelheti a weblap tartalmát.

Amita: Hallottam interfészek programozás. Tudsz még mondani?

Andy: Gondoljon úgy egy interfészre, mint egy specifikációra vagy tervre, hogy hogyan kell viselkednie egy összetevőnek. Az interfész biztosítja az összetevő metódusait vagy viselkedését. A felület azonban nem adja meg a mögöttes részleteket. Ön vagy valaki más létrehozna egy vagy több konkrét osztályt , amelyek implementálják ezt a felületet. A szelén biztosítja a szükséges betonosztályokat.

Ez az ábra a IWebDriver felületet és az ezen felületet megvalósító osztályok közül néhányat mutatja be:

Diagram of the IWebDriver interface, its methods, and concrete classes.

Az ábrán három metódus látható, amelyek IWebDriver a következőt biztosítják: Navigate, FindElementés Close.

Az itt ChromeDriverFirefoxDriverlátható három osztály, valamint EdgeDriveraz egyes implementálási IWebDriver módszerek. Vannak más osztályok, például SafariDriver, amelyek szintén implementálnak IWebDriver. Minden illesztőprogram-osztály szabályozhatja az általa képviselt webböngészőt.

Andy hozzáad egy tagváltozót driver az HomePageTest osztályhoz, például a következő kódhoz:

public class HomePageTest
{
    private IWebDriver driver;
}

A tesztszerelvények meghatározása

Andy: Szeretnénk futtatni a teljes tesztkészletet a Chrome, a Firefox és az Edge rendszeren. Az NUnitban a tesztszerelvényekkel többször futtathatjuk a teljes tesztkészletet, egy alkalommal minden olyan böngészőben, amelyen tesztelni szeretnénk.

Az NUnitban az TestFixture attribútum használatával határozza meg a tesztjavításokat. Andy hozzáadja ezt a három tesztszerelvényt az HomePageTest osztályhoz:

[TestFixture("Chrome")]
[TestFixture("Firefox")]
[TestFixture("Edge")]
public class HomePageTest
{
    private IWebDriver driver;
}

Andy: Ezután meg kell határoznunk egy konstruktort a tesztosztályhoz. A konstruktor akkor lesz meghívva, ha az NUnit létrehozza az osztály egy példányát. Argumentumként a konstruktor a tesztszerelvényekhez csatolt sztringet veszi fel. Így néz ki a kód:

[TestFixture("Chrome")]
[TestFixture("Firefox")]
[TestFixture("Edge")]
public class HomePageTest
{
    private string browser;
    private IWebDriver driver;

    public HomePageTest(string browser)
    {
        this.browser = browser;
    }
}

Andy: Hozzáadtuk a browser tagváltozót, hogy az aktuális böngészőnevet használhassuk a beállítási kódban. Most írjuk meg a telepítési kódot.

A beállítási módszer definiálása

Andy: Ezután ki kell rendelnünk a tagváltozót IWebDriver egy osztálypéldányhoz, amely implementálja ezt a felületet a tesztelt böngészőhöz. A ChromeDriver, FirefoxDriverés EdgeDriver osztályok implementálják ezt a felületet a Chrome, a Firefox és az Edge esetében.

Hozzunk létre egy metódust, Setup amely beállítja a változót driver . Az attribútum használatával azt mondjuk meg az OneTimeSetUp NUnitnak, hogy tesztjavításonként egyszer futtassa ezt a metódust.

[OneTimeSetUp]
public void Setup()
{
}

Setup A metódusban egy switch utasítással rendelhetjük hozzá a driver tagváltozót a böngésző neve alapján a megfelelő konkrét megvalósításhoz. Most vegyük fel ezt a kódot.

// Create the driver for the current browser.
switch(browser)
{
    case "Chrome":
    driver = new ChromeDriver(
        Environment.GetEnvironmentVariable("ChromeWebDriver")
    );
    break;
    case "Firefox":
    driver = new FirefoxDriver(
        Environment.GetEnvironmentVariable("GeckoWebDriver")
    );
    break;
    case "Edge":
    driver = new EdgeDriver(
        Environment.GetEnvironmentVariable("EdgeWebDriver"),
        new EdgeOptions
        {
            UseChromium = true
        }
    );
    break;
    default:
    throw new ArgumentException($"'{browser}': Unknown browser");
}

Az egyes illesztőprogram-osztályok konstruktorának opcionálisan meg kell felelnie a Selenium illesztőprogram-szoftverének, hogy vezérelje a webböngészőt. Később az itt látható környezeti változók szerepét fogjuk megvitatni.

Ebben a példában a EdgeDriver konstruktor további beállításokat is igényel annak megadásához, hogy az Edge Chromium verzióját szeretnénk használni.

A segítő metódusok definiálása

Andy: Tudom, hogy két műveletet kell megismételnünk a tesztek során:

  • Elemek keresése a lapon, például a hivatkozások, amelyekre kattintunk, és a várhatóan megjelenő modális ablakok
  • Kattintson a lapon található elemekre, például a modális ablakokat megjelenítő hivatkozásokra és az egyes modális ablakokat bezáró gombra

Írjunk két segítő metódust, egyet minden művelethez. Kezdjük azzal a módszerrel, amely az oldalon található elemet keresi.

A FindElement segédmetódus írása

Amikor megkeres egy elemet a lapon, az általában valamilyen más eseményre, például az oldal betöltésére vagy az adatokat betöltő felhasználóra reagál. A szelén biztosítja az WebDriverWait osztályt, amely lehetővé teszi, hogy megvárja, amíg egy feltétel igaz lesz. Ha a feltétel nem igaz az adott időtartamon belül, WebDriverWait kivételt vagy hibát jelez. Az osztály használatával WebDriverWait megvárhatjuk, amíg egy adott elem megjelenik, és készen állunk a felhasználói bemenet fogadására.

Ha meg szeretne keresni egy elemet a lapon, használja az osztályt By . Az By osztály olyan metódusokat biztosít, amelyekkel egy elemet a neve, a CSS-osztály neve, a HTML-címke vagy esetünkben az id attribútuma alapján kereshet.

Andy és Amita kódozza a FindElement segédmetódust. A következő kódhoz hasonlóan néz ki:

private IWebElement FindElement(By locator, IWebElement parent = null, int timeoutSeconds = 10)
{
    // WebDriverWait enables us to wait for the specified condition to be true
    // within a given time period.
    return new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutSeconds))
        .Until(c => {
            IWebElement element = null;
            // If a parent was provided, find its child element.
            if (parent != null)
            {
                element = parent.FindElement(locator);
            }
            // Otherwise, locate the element from the root of the DOM.
            else
            {
                element = driver.FindElement(locator);
            }
            // Return true after the element is displayed and is able to receive user input.
            return (element != null && element.Displayed && element.Enabled) ? element : null;
        });
}

A ClickElement segédmetódus írása

Andy: Ezután írjunk egy segédmetódust, amely a hivatkozásokra kattint. A szelén néhány módszert kínál a módszer megírására. Az egyik az IJavaScriptExecutor interfész. Ezzel programozott módon kattinthatunk a hivatkozásokra a JavaScript használatával. Ez a megközelítés jól működik, mert anélkül kattinthat a hivatkozásokra, hogy először görgeti őket a nézetbe.

ChromeDriver, FirefoxDriverés EdgeDriver mindegyik implementáláshoz IJavaScriptExecutor. Az illesztőt erre a felületre kell leadnunk, majd meg kell hívnunk ExecuteScript a JavaScript click() metódus futtatását a mögöttes HTML-objektumon.

Andy és Amita kódozza a ClickElement segédmetódust. A következő kódhoz hasonlóan néz ki:

private void ClickElement(IWebElement element)
{
    // We expect the driver to implement IJavaScriptExecutor.
    // IJavaScriptExecutor enables us to execute JavaScript code during the tests.
    IJavaScriptExecutor js = driver as IJavaScriptExecutor;

    // Through JavaScript, run the click() method on the underlying HTML object.
    js.ExecuteScript("arguments[0].click();", element);
}

Amita: Tetszik az ötlet, hogy ezeket a segítő módszereket. Elég általánosnak tűnnek ahhoz, hogy szinte bármilyen tesztben használják őket. Később szükség szerint további segítő metódusokat is hozzáadhatunk.

A vizsgálati módszer meghatározása

Andy: Most már készen állunk a tesztelési módszer meghatározására. A korábban futtatott manuális tesztek alapján nevezzük ezt a metódust ClickLinkById_ShouldDisplayModalById. Ajánlott olyan leíró neveket adni a tesztelési módszereknek, amelyek pontosan meghatározzák, hogy mit hajt végre a teszt. Itt az attribútuma által id definiált hivatkozásra szeretnénk kattintani. Ezután az attribútum használatával id is ellenőrizni szeretnénk, hogy a megfelelő modális ablak jelenik-e meg.

Andy hozzáadja a tesztmetódus kezdőkódját:

public void ClickLinkById_ShouldDisplayModalById(string linkId, string modalId)
{
}

Andy: Mielőtt további kódot adnánk hozzá, határozzuk meg, mit kell tennie ennek a tesztnek.

Amita: Tudom kezelni ezt a részt. A következőt szeretnénk:

  1. Keresse meg a hivatkozást az attribútuma id alapján, majd kattintson a hivatkozásra.
  2. Keresse meg az eredményként kapott modálist.
  3. Zárja be a modálist.
  4. Ellenőrizze, hogy a modális sikeresen megjelent-e.

Andy: Nagyszerű. Néhány más dolgot is meg kell kezelnünk. Például figyelmen kívül kell hagynunk a tesztet, ha az illesztőprogram nem tölthető be, és csak akkor kell bezárnunk a modálist, ha a modális sikeresen megjelent.

Miután feltöltötte a kávés bögrét, Andy és Amita kódot ad hozzá a tesztelési módszerhez. Az általuk írt segédmetenek segítségével megkeresik az oldalelemeket, majd a hivatkozásokra és gombokra kattintanak. Az eredmény a következő:

public void ClickLinkById_ShouldDisplayModalById(string linkId, string modalId)
{
    // Skip the test if the driver could not be loaded.
    // This happens when the underlying browser is not installed.
    if (driver == null)
    {
        Assert.Ignore();
        return;
    }

    // Locate the link by its ID and then click the link.
    ClickElement(FindElement(By.Id(linkId)));

    // Locate the resulting modal.
    IWebElement modal = FindElement(By.Id(modalId));

    // Record whether the modal was successfully displayed.
    bool modalWasDisplayed = (modal != null && modal.Displayed);

    // Close the modal if it was displayed.
    if (modalWasDisplayed)
    {
        // Click the close button that's part of the modal.
        ClickElement(FindElement(By.ClassName("close"), modal));

        // Wait for the modal to close and for the main page to again be clickable.
        FindElement(By.TagName("body"));
    }

    // Assert that the modal was displayed successfully.
    // If it wasn't, this test will be recorded as failed.
    Assert.That(modalWasDisplayed, Is.True);
}

Amita: A kódolás jól néz ki eddig. De hogyan kapcsolhatjuk ezt a tesztet a id korábban gyűjtött attribútumokhoz?

Andy: Nagy kérdés. Ezt a következő lépésben fogjuk kezelni.

Teszteset adatainak definiálása

Andy: Az NUnitban néhány módon adhat meg adatokat a tesztekhez. Itt az attribútumot TestCase használjuk. Ez az attribútum azokat az argumentumokat veszi fel, amelyeket később a tesztmetódusnak a futtatáskor ad vissza. Több TestCase attribútumunk is lehet, amelyek mindegyike az alkalmazás egy másik funkcióját teszteli. Minden TestCase attribútum létrehoz egy tesztesetet, amely szerepel a folyamatfuttatás végén megjelenő jelentésben.

Andy ezeket az TestCase attribútumokat hozzáadja a tesztmetódushoz. Ezek az attribútumok a Játék letöltése gombot, az egyik játékképernyőt és a ranglista legjobb játékosát írják le. Mindegyik attribútum két id attribútumot határoz meg: egyet a kattintásra szolgáló hivatkozáshoz, egyet pedig a megfelelő modális ablakhoz.

// Download game
[TestCase("download-btn", "pretend-modal")]
// Screen image
[TestCase("screen-01", "screen-modal")]
// // Top player on the leaderboard
[TestCase("profile-1", "profile-modal-1")]
public void ClickLinkById_ShouldDisplayModalById(string linkId, string modalId)
{

...

Andy: Minden TestCase attribútum esetében az első paraméter a id hivatkozáshoz tartozó attribútum, amelyre kattintani szeretne. A második paraméter a id várhatóan megjelenő modális ablak attribútuma. A tesztmetódusban láthatja, hogy ezek a paraméterek hogyan felelnek meg a kétsztringes argumentumoknak.

Amita: Ezt látom. Némi gyakorlattal azt hiszem, hozzáadhatom a saját teszteimet. Mikor láthatjuk ezeket a teszteket a folyamatunkban?

Andy: Mielőtt leküldjük a módosításokat a folyamaton keresztül, először ellenőrizzük, hogy a kód lefordított és helyileg fut-e. Véglegesítjük és leküldjük a módosításokat a GitHubra, és csak azután tekintjük át őket a folyamaton, miután meggyőződtünk arról, hogy minden működik. Most futtassuk helyben a teszteket.