Experimenting with RobotFramework and Selenium

tomerfi

Tomer Figenblat

Posted on August 6, 2020

Experimenting with RobotFramework and Selenium

This is an example C# WebApp tested using Selenium
browser automation with Nunit testing framework for unit tests
and Robot Framework automation framework for acceptance tests.

Base Requirements

  • .Net Core > 3 - written with .Net Core 3.1.102.
  • Python > 3 - written with Python 3.8.2 (used for the acceptance tests).

Before starting, please clone this repository and step into the solution folder.
It will be easier to follow this tutorial, as the next steps will assume you have done so:

git clone https://github.com/TomerFi/selenium-nunit-robotframework-tutorial.git
cd selenium-nunit-robotframework-tutorial
Enter fullscreen mode Exit fullscreen mode

Web Application

In src/DemoWebApp, you'll find a simple C# WebApp created from the basic template provided with dotnet.
On top of the base application, I've added the following:

  • a button tag with the id clickmeButton.
  • a h2 tag with the id displayHeader and the initial content text of Not clicked.
  • a script function called clickButton invoked by a click event from the clickmeButton and changes the displayHeader's content text to Button clicked.

I've added these elements in src/DemoWebApp/Pages/Index.cshtml.
Other than that, I've changed nothing from the basic template:

@page
@model IndexModel
@{
    ViewData["Title"] = "Home page";
}

<div class="text-center">
    <h1 class="display-4">Welcome</h1>
    <p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
    <button id="clickmeButton" type="button" onclick="clickButton()">Click Me!</button>
    <h2 id="displayHeader">Not clicked</h2>
</div>

<script>
function clickButton() {
    document.getElementById("displayHeader").textContent = "Button clicked";
}
</script>
Enter fullscreen mode Exit fullscreen mode

To run the project and serve the app at http://localhost:5000:

dotnet run -p src/DemoWebApp
Enter fullscreen mode Exit fullscreen mode

Unit Testing

In tests/DemoWebApp.Tests, you'll find the test project for performing unit tests; I've used:

  • Nunit as the testing framework for the project.
  • Selenium as the toolset providing browser capabilities and automation.

tests/DemoWebApp.Tests/DemoWebAppTest.cs is a test class, Nunit will pick it up based on its name:

I've used the OneTimeSetup attribute to spin up the server before executing the test cases:

[OneTimeSetUp]
public void SetUpWebApp()
{
    app = DemoWebApp.Program.CreateHostBuilder(new string[] { }).Build();
    app.RunAsync();
}
Enter fullscreen mode Exit fullscreen mode

And the OneTimeTearDown attribute to shut down the server afterward.

[OneTimeTearDown]
public void TearDownWebApp()
{
    app.StopAsync();
    app.WaitForShutdown();
}
Enter fullscreen mode Exit fullscreen mode

The test itself is pretty straightforward:

  • It first navigates to the server at http://localhost:5000.
  • It will then find the button element by its id and click it.
  • Finally, it will make sure the h2 element's content text is Button clicked.

The assert statement evaluates the clicked boolean value
which will be false if the expected test conditions are not met within 10 seconds.

public void TestButtonClick(Type drvType)
{
    bool clicked;
    using (var driver = (IWebDriver)Activator.CreateInstance(drvType))
    {
        var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
        driver.Navigate().GoToUrl("http://localhost:5000");
        driver.FindElement(By.Id("clickmeButton")).Click();

        clicked = wait.Until(ExpectedConditions.TextToBePresentInElement(
            driver.FindElement(By.Id("displayHeader")), "Button clicked"));
    }
    Assert.True(clicked, "button not clicked.");
}
Enter fullscreen mode Exit fullscreen mode

The test cases will invoke the TestButtonClick test 3 times, one for each TestCase.
The result will be three tests performed, one with the chrome driver, one with the firefox driver, and one with the ie driver.

[TestCase(typeof(ChromeDriver))]
[TestCase(typeof(FirefoxDriver))]
[TestCase(typeof(InternetExplorerDriver))]
public void TestButtonClick(Type drvType)
{
    ...
}
Enter fullscreen mode Exit fullscreen mode

To check it out, just:

dotnet test
Enter fullscreen mode Exit fullscreen mode

Acceptance Testing

For acceptance tests, I've used:

For the next steps, step into the acceptance folder.
The acceptance tests don't have, nor should they have, any direct
connection to the solution's base code.

Prepare Environment

Robot Framework is a Python tool requiring a binary and some dependencies.
Assuming you have Python installed, and you're in the acceptance folder,
Just do:

pip install --upgrade -r requirements.txt
Enter fullscreen mode Exit fullscreen mode

As this is the acceptance tests part, the tests need a web server serving the web app.
You can follow the Web Application section to run the web app locally or as you see fit.
Don't forget to set the URL variable in acceptance/resources.robot to the correct address:

${URL}              http://localhost:5000
Enter fullscreen mode Exit fullscreen mode

Please note, markdown doesn't support robotframework syntax highlighting natively.
There's another version of this tutorial in restructuredText which supports robotframework syntax highlighting
here.

Drivers

You can download the drivers stored in acceptance/drivers with the following links.
Just mind the versions and make sure they're in conjunction with the versions used in
tests/DemoWebApp.Tests/DemoWebApp.Tests.csproj:

<ItemGroup>
    <PackageReference Include="Selenium.WebDriver.ChromeDriver" Version="83.0.4103.3900" />
    <PackageReference Include="Selenium.WebDriver.IEDriver" Version="3.150.1" />
    <PackageReference Include="Selenium.Firefox.WebDriver" Version="0.26.0" />
</ItemGroup>
Enter fullscreen mode Exit fullscreen mode

To save you the trouble, here are the links for the drivers download:

Tests

acceptance/webapp_tests.robot is the test suite.
It declares 3 Test Cases, one for each driver.
Each test case uses Test Template with its own Browser and Executable arguments.
Make sure the driver executables are in the correct path.

*** Settings ***
...
Test Template    Press Button

*** Test Cases ***             Browser    Executable
Test With Chrome               chrome     drivers/chromedriver
Test With Internet Explorer    ie         drivers/iedriver
Test With Firefox              firefox    drivers/geckodriver
Enter fullscreen mode Exit fullscreen mode

The Test Template invokes the keyword named Press Button,
For each execution, what Press Button does is pretty self-explanatory by its BDD nature:

*** Keywords ***
Press Button
    [Arguments]    ${browser}    ${executable}
    Open Browser With Url    ${browser}    ${executable}
    Click Test Button
    Validate New Text
    [Teardown]    Close Browser
Enter fullscreen mode Exit fullscreen mode

The result of running this test suite will be three tests, one for each driver, each pressing the button and validating the side effects.

The Press Button uses four other keywords to perform its action.
As you can see in the Settings section, I've declared acceptance/resources.robot as a resource.
It provides us with the following custom keywords:

  • Open Browser With Url
  • Click Test Button
  • Validate New Text

The 4th keyword, Close Browser, is not a custom one; it comes from SeleniumLibrary, imported within acceptance/resources.robot:

*** Settings ***
...
Library          SeleniumLibrary
Enter fullscreen mode Exit fullscreen mode

This SeleniumLibrary library is also used by the custom keywords in acceptance/resources.robot.

To execute the acceptance tests, run the following:

robot -d rfoutput webapp_tests.robot
Enter fullscreen mode Exit fullscreen mode

This will run the tests and save a pretty and valuable HTML report summary and XML logs in a folder called rfoutput (gitignored).
You can see an example of the summary report here.

Links

💖 💪 🙅 🚩
tomerfi
Tomer Figenblat

Posted on August 6, 2020

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related