23 Stimmen

Wie kann ich meine Selenium-Tests weniger spröde machen?

Wir verwenden Selenium, um die UI-Schicht unserer ASP.NET-Anwendung zu testen. Viele der Testfälle testen längere Abläufe, die sich über mehrere Seiten erstrecken.

Ich habe festgestellt, dass die Tests sehr fragil sind, nicht nur durch Code-Änderungen, die tatsächlich die Seiten ändern, sondern auch durch harmlose Refactorings wie die Umbenennung eines Steuerelements (da ich die ClientID des Steuerelements an die Klickmethode von Selenium übergeben muss, usw.) oder den Austausch eines GridViews durch einen Repeater. Als Ergebnis finde ich mich 'verschwende' Zeit damit, Zeichenfolgenwerte in meinen Testfällen zu aktualisieren, um defekte Tests zu beheben.

Gibt es einen Weg, um wartbarere Selenium-Tests zu schreiben? Oder ein besseres Web-UI-Testwerkzeug?

Bearbeitet, um hinzuzufügen: Normalerweise wird der erste Entwurf erstellt, indem ein Test im IDE aufgezeichnet wird. (Dieser erste Schritt kann vom QA-Personal durchgeführt werden.) Dann refaktoriere ich den generierten C#-Code (Extrahiere Konstanten, extrahiere Methoden für wiederholten Code, wiederhole möglicherweise den Testfall mit unterschiedlichen Daten, usw.). Aber der allgemeine Codefluss für jeden Testfall bleibt ziemlich nahe am ursprünglich generierten Code.

0 Stimmen

11voto

MariangeMarcano Punkte 921

Ich finde das PageObject-Muster sehr hilfreich.

http://code.google.com/p/webdriver/wiki/PageObjects

mehr Infos: - Was ist der Sinn von Selenium? - Selenium-Kritik

Vielleicht ist ein guter Weg, um anzufangen, Ihre Testfälle schrittweise zu refaktorisieren.

Ich verwende das gleiche Szenario wie Sie: Selenium + C#

So sieht mein Code aus:

Ein Testfall könnte ungefähr so aussehen

    [TestMethod]
    public void RegisterSpecialist(UserInfo usrInfo, CompanyInfo companyInfo)
    {
        var RegistrationPage = new PublicRegistrationPage(selenium)
              .FillUserInfo(usrInfo)
              .ContinueSecondStep();
        RegistrationPage.FillCompanyInfo(companyInfo).ContinueLastStep();
        RegistrationPage.FillSecurityInformation(usrInfo).ContinueFinishLastStep();
        Assert.IsTrue(RegistrationPage.VerifySpecialistRegistrationMessagePayPal());
        selenium.WaitForPageToLoad(Resources.GlobalResources.TimeOut);
        paypal.LoginSandboxPage(usrInfo.sandboxaccount, usrInfo.sandboxpwd);
        Assert.IsTrue(paypal.VerifyAmount(usrInfo));
        paypal.SubmitPayment();
        RegistrationPage.GetSpecialistInformation(usrInfo);
        var bphome = new BPHomePage(selenium, string.Format(Resources.GlobalResources.LoginBPHomePage, usrInfo.AccountName, usrInfo.Password));
        Assert.IsTrue(bphome.VerifyPageWasLoaded(usrInfo));
        Assert.IsTrue(bphome.VerifySpecialistProfile());
        bphome.Logout();
    }

Ein Page-Objekt wird ungefähr so aussehen

public class PublicRegistrationPage
{
    public ISelenium selenium { get; set; }

    #region Constructors
    public PublicRegistrationPage(ISelenium sel)
    {
        selenium = sel;
        selenium.Open(Resources.GlobalResources.PublicRegisterURL);
    }
    #endregion
    #region Methods

    public PublicRegistrationPage FillUserInfo(UserInfo usr)
    {
        selenium.Type("ctl00_cphComponent_ctlContent_wizRegister_tUserFirstName", usr.FirstName);
        selenium.Type("ctl00_cphComponent_ctlContent_wizRegister_tUserLastName", usr.LastName);
        selenium.Select("ctl00_cphComponent_ctlContent_wizRegister_ddlUserCountry", string.Format("label={0}",usr.Country ));
        selenium.WaitForPageToLoad(Resources.GlobalResources.TimeOut);
        selenium.Type("ctl00_cphComponent_ctlContent_wizRegister_tUserEmail", usr.Email );
        selenium.Type("ctl00_cphComponent_ctlContent_wizRegister_tUserDirectTel", usr.DirectTel);
        selenium.Type("ctl00_cphComponent_ctlContent_wizRegister_tUserMobile", usr.Mobile);
        return this;
    }

}

Ich hoffe, das hilft.

3voto

cynicalman Punkte 5781

Wie erstellen Sie Ihre Selenium-Tests, indem Sie sie aufzeichnen und wieder abspielen? Was wir gemacht haben, ist ein Objektmodell um Seiten herum aufzubauen, so dass Sie eine Methode wie "clickSubmit()" aufrufen, anstatt auf eine id zu klicken (mit einer Namenskonvention für diese ids), was es den Selenium-Tests ermöglicht, viele Änderungen zu überstehen.

2voto

Precipitous Punkte 5103

Sie können möglicherweise Tests schreiben, die beim Refactoring widerstandsfähig sind oder auch nicht. Hier ist, wie man das Refactoring weniger schmerzhaft macht: Kontinuierliche Integration ist unerlässlich.

Führen Sie sie jeden Tag oder bei jedem Build aus. Je schneller es behoben ist, desto einfacher.

Stellen Sie sicher, dass Entwickler die Tests selbst ausführen können. Auch hier gilt: Je schneller es gesehen und behoben wird, desto einfacher.

Halten Sie die Selenium-Tests knapp. Sie sollten sich auf kritische Pfade / Priority-1-Test-Szenarien konzentrieren. Tiefgehende Tests sollten auf Einheitstestebene (oder jsunit-Tests) durchgeführt werden. Integrationstests sind immer teuer und weniger wertvoll.

1voto

Artem Punkte 6865

Das Anknüpfen an beliebige Low-Level-Konzepte wie XPaths, CSS-Selektoren oder IDs für End-to-End-Tests ist ein Rezept für instabile Tests. Ich empfehle die Verwendung von testRigor, um Tests zu erstellen, die nicht jedes Mal kaputtgehen, wenn Sie Ihre Anwendung ein wenig ändern/verbessern. Der dem oben stehenden Seitenelementobjekt entsprechende Code würde so aussehen:

    Geben Sie "Peter" in "Vorname" ein
    Geben Sie "Pen" in "Nachname" ein
    Geben Sie "US" in "Land" unter "Benutzerdaten" ein
    Geben Sie den gespeicherten Wert "E-Mail" in "E-Mail" ein
    Geben Sie den gespeicherten Wert "Passwort" in "Passwort" ein
    Geben Sie "415-123-4567" in "Direktnummer" ein
    Geben Sie "415-123-4568" in "Mobilnummer" ein
    Klicken Sie auf "Senden"

testRigor würde Texte, die wie Beschriftungen aussehen, mit den Eingabefeldern verknüpfen, sodass die testRigor-Skripte sofort grün werden, sobald Ihre Seite aus der Sicht eines Endbenutzers gleich aussieht. Hier ist die Dokumentation.

Haftungsausschluss: Ich bin Mitgründer von testRigor. Ich habe mitgegründet, weil wir genau diese Probleme selbst hatten.

Ich hoffe, das hilft.

0voto

Patrick Cuff Punkte 27220

Es gibt keine harmlosen Änderungen, wenn es um Testautomatisierung geht ;)

Wir verwenden das SAFS-Framework mit Rational Robot (RRAFS), um die Auswirkungen auf unsere Automatisierungsskripte zu minimieren. Es ist immer noch Arbeit, die Anwendungskarte zu pflegen, aber die Skripte bleiben größtenteils stabil. Das SAFS-Framework klingt sehr ähnlich wie die Methode, die cynicalman erwähnt, aber packt bereits die generischen Methoden ein, die Sie in Ihren Skripten verwenden würden.

Die SAFS-Website sagt, dass es teilweise Unterstützung für Selenium gibt, daher könnte dies für Sie funktionieren.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X