Testing

Interesting articles

Selenium

Selenium IDE - Firefox add on to provide simple GUI for creating tests Selenium RC/Web Driver - Java API for creating browser executed tests

Good Blog on Testing stuff: http://www.nearinfinity.com/blogs/testing/

When using the Selenium Web Driver you have to keep up to date on the libs to allow you to launch the latest versions of Firefox etc.

Below is an example taken from the selenium website of a basic scenario using the WebDriver.

package selenium;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;

public class Selenium2Example {

    public static void main(String[] args) {
        // Create a new instance of the Firefox driver
        // Notice that the remainder of the code relies on the interface, 
        // not the implementation.
        WebDriver driver = new FirefoxDriver();

        // And now use this to visit Google
        driver.get("http://www.google.com");

        // Find the text input element by its name
        WebElement element = driver.findElement(By.name("q"));

        // Enter something to search for
        element.sendKeys("Cheese!");

        // Now submit the form. WebDriver will find the form for us from the element
        element.submit();

        // Check the title of the page
        System.out.println("Page title is: " + driver.getTitle());

        //Close the browser
        //driver.quit();
    }

}

JUnit testing with Java

JUnit 5

Using Tag to include/exclude tests

  • Tag("integration-test") - can tag unit tests with Tag annotation to allow you to group tests
  • Intellij JUnit configuration can use "Test Kind" drop-down with "Tag" value to allow filtering by tags for running tests
  • Can exclude a tag with "!my-tag-name"

Asserting exceptions


// JUnit4
@Test(expected = NullPointerException.class)
public void whenExceptionThrown_thenExpectationSatisfied() {
    String test = null;
    test.length();
}

// JUnit5
@Test
public void whenExceptionThrown_thenAssertionSucceeds() {
    Exception exception = assertThrows(NumberFormatException.class, () -> {
        Integer.parseInt("12345aa");
    });

    String expectedMessage = "For input string";
    String actualMessage = exception.getMessage();

    assertTrue(actualMessage.contains(expectedMessage));
}

Frameworks

Mockito

Principle is to mock dependencies and provide expected results

  @Test
  public void testGetIssueCurrency() {
    final String CURRENCY_EUR = "EUR";
    AmountInfoForAllPax amountInfoForAllPax = new AmountInfoForAllPax();
    ItineraryAmounts mockItineraryAmounts = Mockito.mock(ItineraryAmounts.class);
    Mockito.when(mockItineraryAmounts.getCurrencyMonetaryDetailByType(anyString())).thenReturn(CURRENCY_EUR);

    amountInfoForAllPax.setItineraryAmounts(mockItineraryAmounts);
    assertEquals(amountInfoForAllPax.getIssueCurrency(), CURRENCY_EUR);
  }
  • Can also use verify() to make sure that certain methods are called.

PowerMock

TODO - but maybe less useful since manipulating classes

Geb Testing Framework

http://www.gebish.org/

From the site: <pre> Geb is a browser automation solution.

It brings together the power of WebDriver, the elegance of jQuery content selection, the robustness of Page Object modelling and the expressiveness of the Groovy language.

It can be used for scripting, scraping and general automation — or equally as a functional/web/acceptance testing solution via integration with testing frameworks such as Spock, JUnit & TestNG.

The Book of Geb contains all the information you need to get started with Geb. </pre>

Robot Framework

Robot is a framework which is "language agnostic" and aimed at automating testing with a type of Python based scripts + libraries to integrate

JUnit etc. - TODO merge with sections above

Mockito - Partial Mocking and Spying

  • Partial Mocking - call Mock for all methods unless a method is explicitly marked as calling real method
  • Spying - call real for all methods unless a method is explicitly marked as being mocked.

See the Mockito documentation on partial mocks for more information.

Stock stock = mock(Stock.class);
when(stock.getPrice()).thenReturn(100.00); // Mock implementation
when(stock.getQuantity()).thenReturn(200); // Mock implementation
when(stock.getValue()).thenCallRealMethod(); // Real implementation

In that case, each method implementation is mocked, unless specify thenCallRealMethod() in the when(..) clause. There is also a possibility the other way arround with spy instead of mock:

Stock stock = spy(Stock.class);
when(stock.getPrice()).thenReturn(100.00);    // Mock implementation
when(stock.getQuantity()).thenReturn(200);    // Mock implementation// All other method call will use the real implementations

There is one important pitfall when you use when(Object) with spy like in the previous example. The real method will be called (because stock.getPrice() is evaluated before when(..) at runtime). This can be a problem if your method contains logic that should not be called. You can write the previous example like this:

Stock stock = spy(Stock.class);
doReturn(100.00).when(stock).getPrice();    // Mock implementation
doReturn(200).when(stock).getQuantity();    // Mock implementation// All other method call will use the real implementations

Mockito - any() and raw values

When using the any() (e.g. anyInt()) in a Mockito matcher, all parameters must be matchers, you can't use raw values (like - Constants.SOME_STRING). To get around this, the eq() method will allow you to use the constant values.

when(someObj.someMethod(eq(metas), any(List.class), anyInt(), any(Config.class))).thenReturn(someResponse);

Mockito - stub() when() and given() - when to use what

http://stackoverflow.com/questions/14736219/difference-between-stub-and-when-in-mockito

  • stub() - original version
  • when() - when interactions became fashionable
  • given() - now that BDD is fashionable

Mockito - with mocking Class<?> style objects http://stackoverflow.com/questions/7366237/mockito-stubbing-methods-that-return-type-with-bounded-wild-cards

JUNIT Testing Hamcrest

  • Using the hamcrest form of asserts
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.nullValue;

    Assert.assertThat(preferencesList, is(nullValue()));

Mockito and Dependency Injection

https://blog.jayway.com/2012/02/25/mockito-and-dependency-injection/

@RunWith(MockitoJUnitRunner.class)
public class ExampleTest {

    @Mock
    Delegate delegateMock;

    @InjectMocks
    Example example;

    @Test
    public void testDoIt() {
        example.doIt();
        verify(delegateMock).execute();
    }
}

JUnit setting env variables

Especially in multithreaded tests, if you have a static class calling System.getenv() then you can get into trouble. This is because the environment variables are set at the start of the JVM and are not updated when you change them in the test. Even Mockito mock static can have issues in multi-threaded tests.

<dependency>
    <groupId>uk.org.webcompere</groupId>
    <artifactId>system-stubs-jupiter</artifactId>    
    <scope>test</scope>
</dependency>
// Add the extension to the test class
@ExtendWith(SystemStubsExtension.class)
class EnvironmentVariablesUnitTest {
}

// For a test where we know in advance the value we can set it as a variable with creation, otherwise can do a beforeEach method
@SystemStub
private EnvironmentVariables environment = new EnvironmentVariables("MY_VARIABLE", "is set");

// Now when we call System.getEnv("MY_VARIABLE") we will get "is set"

JUnit - reading for a log message

Miscellaneous Testing

Load Testing

  • Link to new page for load testing - TODO - link to testing:loadtesting

Restful Resources Testing - Postman and Newman

  • link to postman page - TODO - link to testing postman page