Kategorier
Test and Q&A

Selenium C# Page Object Model utan PageFactory

PageFactory för Selenium C# har from. version 3.11 utgått. Det har under en övergångsperiod gått att använda med ett tilläggspaket (NuGet) som heter DotNetSeleniumExtras.PageObjects men från version 4 av Selenium stöds inte heller det.

PageFactory anses av flera inom Selenium-community inte vara ett bra stöd i konceptet Page Object Model (POM), även om jag själv inte haft några problem med det. Längst ner i detta inlägg finns några länkar till anledningen bakom att sluta stödja PageFactory, om du vill veta mer.

Vad är då PageFactory? Jo det används för att initiera webbelement i POM-classen och elementen får därför en funktion som liknar cachning. Denna bild från guru99.com visar bra hur man definierar webbelement med PageFactory:

Från guru99.com

Om man vill uppgradera sitt Selenium-projekt till version 4, vilket är bra för att få nya funktioner och eventuella säkerhetspatchar, krävs det att man konverterar @FindBy till FindElement vilket får till följd att webbelementen letas upp under runtime när testet körs. Det är egentligen ganska lätt att konvertera men kan ta lite tid. I det projekt jag jobbar med nu var det ca. 700 webbelement som fick konverteras manuellt, men egentligen utan några större problem.

Om ett element i PageFactory ”hittades” så här:

        [FindsBy(How = How.Id, Using = "account")]
        public IWebElement MyAccount { get; set; }

Så får man konvertera det till:

public IWebElement MyAccount => _driver.FindElement(By.Id("account"));

Och sen får man ta bort initieringen av PageFactory och till slut avinstallera NuGet-paketet DotNetSeleniumExtras.PageObjects.

Det jag upptäckt efter konverteringen är att vissa delar av testerna har varit anpassad för PageFactory och beter sig nu lite annorlunda. Ett exempel är om man vill kolla om ett webbelement finns på sidan (i DOM:en), tex. om en knapp ska synas eller inte. Beroende på vilket front-end ramverk som används kanske elementet bara är ”hidden” eller ”not enabled” men det kan även vara så att det inte finns alls. Just det fallet kan man lösa genom följande:

Skapa en generell metod (här i classen BasePage.cs) som sätter ner tiden (här till 5 sekunder) hur länge Seleniums webdriver ska vänta på ett element är tillgängligt i DOM:en. Om du inte sätter ner tiden får du vänta i den tid som gäller generellt för ImplicitWait, i mitt fall 30 sekunder (timeSpan).
Om elementet sedan är tillgängligt returneras true, annars false eftersom ett NoSuchElement-exception kan kastas och det tas hand om med catch.
Observera att ImplicitWait sätts tillbaka till 30 sekunder när resultatet returneras vilket innebär att resten av testmetoden som exekveras åter har webdrivern med sitt ursprungsvärde.

        public bool IsElementDisplayed(string elementToCheck, int time = 5)
        {           
            Driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(time);
           
            var present = false;
            try
            {
                IWebElement element = Driver.FindElement(By.Id(elementToCheck));
                present = element.Displayed;
            }
            catch (Exception)
            {
                            
               //Set back ImplicitWait to default 
                Driver.Manage().Timeouts().ImplicitWait = timeSpan;
                return present;
            }
            //Set back ImplicitWait to default 
            Driver.Manage().Timeouts().ImplicitWait = timeSpan;
            return present;
        }

Och i din testmetod, anropa metoden med webbelementet som en textsträng. Då får du en snygg assert som du kan hantera som du vill:

Assert.IsTrue(BasePage.IsElementDisplayed("sitelogo"), "Site logo not visible");

Det finns många olika sätt att hantera liknande fall och det aktuella behovet får avgöra hur du väljer att implementera. I mitt projekt var det enklast att göra på detta vis då vi har många tester om element syns (finns) eller inte i DOMen.

Om du överväger att komma bort från PageFactory för att kunna uppgradera till Selenium 4 hoppas jag att du fått lite ideer av mitt inlägg. Till slut kommer här ett antal länkar om du vill läsa mer om bakgrunden till PageFactory och varför den supporten nu upphör.

Lars Thunberg – Q&A-konsult inom testledning, systemtestning och testautomatisering

Kategorier
Test and Q&A

Use animated GIFs in TFS bug reports

In Microsoft Team Foundation Server (TFS) bug reporting tool it is not so simple to add recorded videos of bug. To record bug scenarios can be very time effective for a developer when receiving the bug reports.

The best way, as we use in my current project/assignment, is to record the bug with a tool called ScreenToGif. Is is very simple to record your movement on the screen and convert the small video to an animated GIF image.

The animated GIF image can then be imported (added) as a image direct in the TFS bug report and can be viewed without any tools direct in the web TFS web interface.
I can highly recommend this way of working with bugs in TFS!

Click for see the animated GIF

Kategorier
Test and Q&A

Visual regression testing med Selenium

I senaste numret av Professional Tester magazine beskriver Viv Richards ett ramverk för visuell regressiontestning med Selenium webdriver. Jag kommer inte gå in i detalj hur det fungerar utan jag hänvisar till artikeln i PT eller Viv Richards blog. Jag har testat ramverket (skrivet i C#) dels direkt från det exempel-projekt som finns men även att implementera det i en Selenium Base Page Object-lösning.

I det stora hela fungerar det mycket bra. På bara några timmar var jag igång med en fungerande PoC. Jag ger här några exempel och delar med mig av erfarenheter och problem jag stött på.

Anropet är mycket enkelt:

// Arrange
var baseImage = "TechnicalPage_Base.png";

// Act
var difference = GetDifference(Driver, baseImage);

// Assert
Assert.IsTrue(difference == 0);

Ramverket ger även en enkel men fullt fungerande testrapport. Nedan ser ni en lyckad testkörning och en misslyckad (failed):

Testresultat som HTML-sida

 

Kollar man vidare på det test som gav failed (i detta fall en enkel testsida jag gjort) ger skillnaden, dvs. det visuella felet, en bild med rosa markeringar på. Det kan vara svårt att se på exemplet nedan (klicka för större bild) men jag har ersatt två a med svenska tecken ö och å som ramverket upptäckte. Kontroll görs ner på pixelnivå:

Bild som markerar fel

Det som givetvis inte går att testa med visuell automatisering är dynamiskt innehåll (tex. Twitter-flöden). Det är givetvis inte möjligt ens med manuell testning… Det finns dock en inbyggd funktion för att skugga bort dessa partier:

// Cover specified dynamic element on page with blanket
CoverDynamicElementBySelector(Driver, elementByCssSelector);

Och då blir det visuella resultatet enligt följande:

Dölj dynamiskt innehåll

Det jag inte lyckats med att visuellt testa är inbäddade länkar från YouTube i WordPress. Här verkar det som om färgerna på den stillbild YouTube levererar blir olika ibland och därmed detekterar ramverket detta som förändring på pixelnivå.

Det som också beskrivs av Viv Richards är att det är viktigt att skapa basbilderna med den Selenium webdriver som ska utföra regressionstesterna. Det går inte att manuellt lägga till en bild.

Ramverket finns att testa och ladda ner från GitHub:
https://github.com/vivrichards600/AutomatedVisualTesting

Kategorier
Test and Q&A

Excel file regression test with C#

In my current assignment / project we are running regression tests of text, csv and excelfiles. The system is based on .NET / C# and daily builds. Every night the checked in developed code is built and the system is built up from scratch. A number of output files should be the same as the day before i.e. regression test.

For C# there are a lot of ready solutions for comparing (diffs) excel files but we had no such at hands. We needed to built this on our own.

First I needed to convert excel files to csv files in order to make an easy compare/diff. For this I’m using a Visual Basic script that has been published on many sites.

 

XlsToCsv.vbs

if WScript.Arguments.Count < 2 Then
WScript.Echo "Please specify the source and the destination files. Usage: ExcelToCsv <xls/xlsx source file> <csv destination file>"
Wscript.Quit
End If

csv_format = 6

Set objFSO = CreateObject("Scripting.FileSystemObject")

src_file = objFSO.GetAbsolutePathName(Wscript.Arguments.Item(0))
dest_file = objFSO.GetAbsolutePathName(WScript.Arguments.Item(1))

Dim oExcel
Set oExcel = CreateObject("Excel.Application")

Dim oBook
Set oBook = oExcel.Workbooks.Open(src_file)

oBook.SaveAs dest_file, csv_format

oBook.Close False
oExcel.Quit

To use it just ”Please specify the source and the destination files. Usage: ExcelToCsv <xls/xlsx source file> <csv destination file>”. You can call it from C# in the same way as you diff files (see below).

In order to diff files I use the FC tool in windows and call this from C# with Process.start. Here is a sample code:

string strCmdText = "/C c:/Windows/system32/fc /L ";                
Process P = Process.Start("CMD.exe", strCmdText + fileno1todiff + fileno2todiff);
P.WaitForExit();

//Exit codes from the differ
// -1 – Your syntax is incorrect.
// 0 – Both files are identical.
// 1 – The files are different.
// 2 – At least one of the files can’t be found.

int result = P.ExitCode;
//Make an assert check
Assert.AreEqual(0, result);

So this is a simple way to regression test excel files in C# with simple scripts.

Kategorier
Test and Q&A

Enhetstester i C# med JUnit

Efter många år som testare och testledare med inriktning funktionella system- och acceptanstester har jag nu fått möjlighet att deltaga i ett projekt runt framtagandet av ett API.

Här krävdes andra metoder än manuell testning och jag fick då möjlighet att gräva ner mig i enhetstester med C# och ramverket JUnit. 

Som ”gammal” avdankad utvecklare fick jag stor hjälp av mina kollegor på Triona som skrev basen runt testerna. Sedan kunde jag bara fylla på med just de enhetstester som behövdes med enkel C#-kod.

Enhetstesterna skrivs och markeras som test:

junit_1

Sedan körs testerna och presenteras snyggt:

junit_2

Mina kollegor kommer sedan paketera detta på ett sätt att testerna körs automatiskt varje gång systemet byggs.
Snyggt!

Kategorier
Test and Q&A

yUML – enkelt verktyg för att skapa UML-diagram

Jag fick ett tips från en kollega om online-verktyget yUML som gör det enkelt att snabbt skapa UML-diagram, tex. för användningsmodeller.

Med hjälp av ett mycket enkelt scriptspråk byggs modellerna upp:

[Customer]-(Sign In)
[Customer]-(Buy Products)
(Buy Products)>(Browse Products)
(Buy Products)>(Checkout)
(Checkout)<(Add New Credit Card)

Resultatet kan länkas på flera sätt, tex. som en bild (detta är alltså en direkt länk till verktyget, inte en lokal bild):

Ett mycket bra verktyg som jag nu använder!

Kategorier
Test and Q&A

Att bli respekterad som testledare i projektet

Under de år jag arbetat som testledare och testare har jag kommit fram till att följande punkter är en väg till att bli respekterad som testledare i ett projekt:

  • Lär dig systemet i grunden. Testa mycket själv, sitt och ”lek” med alla funktioner. Som testledare ska du inte kunna allt i detalj men vara bäst på helheten. Lägg mycket tid på detta!
  • Var jobbig med kravfrågorna – är det testbart? Du kommer till slut få respekt för ditt kunnande runt kraven.
  • Plugga in kraven – lär dig dessa lika bra som systemet.
  • Prata med användarna och beställarna. Gör detta ”utanför” projektplanen, dvs. var inte så hård att boka möten och workshops. Ta hellre en kaffe med en av beställarna, lär känna honom/henne och verksamhetens behov. Då blir du en bättre kvalitétssäkrare = (testare/testledare)!
  • Hjälp projektledaren. Hela tiden…  Du ska när som helst kunna driva projektet en kortare period tex. vid sjukdom från projektledare.  Om du kan driva projektet en kortare period blir du även bättre att kvalitetssäkra.
  • Vidga ditt synsätt / uppdrag. Se ditt arbete som kvalitetssäkring, inte bara test av programvara.

Ovanstående fungerar bra för mig i praktiken. Håller du med – eller inte?  Kommentera gärna genom att klicka på ”bubblan” till höger om rubriken!