home.


Tagged: java-testing


Using HtmlUnit, Selenium and Bootstrap

If you using Selenium’s HtmlUnit driver on a website with Bootstrap, you must disable Javascript support.

HtmlUnitDriver driver = new HtmlUnitDriver(false);

Otherwise you’ll find this exception

org.openqa.selenium.ElementNotVisibleException: You may only interact with visible elements

This is because HtmlUnit’s Javascript support is patchy and doesn’t seem to work well with Bootstrap’s Javascript.

(I’m using HtmlUnit 2.12)

There may be a way around this to do with jQuery versions, I’ve read.

But if your website works without Javascript, then just testing without Javascript may be a solution.

Otherwise, PhantomJs seems to be another solution.

java bootstrap java-testing selenium

Java: Testing a REST service with a clean database (using sqlite)

You can test REST responses like so with Jersey’s client api.

    YourResponseObject result = service
       .path("somepath")
       .type(MediaType.APPLICATION_JSON)
       .put(YourResponseObject.class, yourInputObject);

    assertTrue(result.isSuccessful());

But your responses may depend on the state of your database.

And since you’re not running your tests from a WAR, or what have you, you have no direct access to populate its seed or delete it.

The best way to do this is to create a rest method to clear the database to use during development, and remove in production.

The method to delete the database would look like:

    EntityTransaction trans = mEntityManager.getTransaction();
    trans.begin();
    Query q = mEntityManager.createQuery("delete from UserEntity");
    q.executeUpdate();
    trans.commit();
    closeEntityConnection();

It may be possible access the JPA database if the tests are run in a WAR, but I haven’t tried that. Any experience would be welcomed in the comments.

java REST java-testing jersey sqlite jpa

Tomcat 7: Testing REST interfaces with Jersey

You can test REST services with Jersey’s client library easily enough.

 public class RestTest {
  @Test
  public void addAnotherThing() {
    // Arrange
    ClientConfig config = new DefaultClientConfig();
    Client client = Client.create(config);
    WebResource service = client.resource(getBaseURI());
    // Act
    String result = service.path("rest").path("r").accept(MediaType.TEXT_PLAIN).get(String.class);
    // Assert
    assertEquals("Get should be 'rest'", "rest", result);
   }     
   private static URI getBaseURI() {
     return UriBuilder.fromUri("http://localhost:8080/hiya/rest/").build();
   }
 }

In this you use the Jersey ClientConfig, Client and WebResource to eventually make a url request that accepts plain text and get a string from that, finally asserting that to be a specific value.

java jersey REST java-testing

JPA: Testing

You can test your JPA code by setting aside another folder structure, test/ for example, with a META-INF/ directory with a new persistence.xml file there pointing to a different database.

Here’s new new persistence.xml:

 <?xml version="1.0" encoding="UTF-8" ?>
 <persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
     version="2.0"
     xmlns="http://java.sun.com/xml/ns/persistence">
   <persistence-unit name="example" transaction-type="RESOURCE_LOCAL">
     <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
     <class>org.denevell.tomcat.entities.write.AnotherThing</class>
     <properties>
       <property name="javax.persistence.jdbc.driver" value="org.sqlite.JDBC" />
       <property name="javax.persistence.jdbc.url" value="jdbc:sqlite:/home/YOURUSERNAME/test.db" />
       <property name="eclipselink.logging.level" value="ALL" />
       <property name="eclipselink.ddl-generation" value="drop-and-create-tables" />
     </properties>
   </persistence-unit>
</persistence>

The only different to the previous ones is that we’re putting our database in a new location - one where the runner of the junit test has write access. And we’re doing drop-and-create-tables in the table creation.

The next thing you need is the junit4 file that calls the persistence provider to test adding of the entity:

public class JPAStarterTest {
  @Test
  public void addAnotherThing() {
    // Arrange
    AnotherThing at = new AnotherThing();
    at.setText("hii");          
    // Act
    tx.begin();
    em.persist(at);
    tx.commit();            
    // Assert
    assertNotNull("Id should not be null", at.getId());
    List<AnotherThing> list = em.createNamedQuery("listAll", AnotherThing.class).getResultList();
    assertEquals("Table has one entity", 1, list.size()); 
    assertEquals("Table has correcttext", "hii", list.get(0).getText());
  }

  @BeforeClass
  public static void beforeClass() {
    emf = Persistence.createEntityManagerFactory("exampletest");
    em = emf.createEntityManager();
  }

  @AfterClass
  public static void afterClass() {
    em.close();
    emf.close();
  }

  @Before
  public void before() {
    tx = em.getTransaction();
  }
  private static EntityManagerFactory emf;
  private static EntityManager em;
  private EntityTransaction tx; 
}

Now when you run this, ensure your new persistence.xml is in the META-INF/ directory of the classes.

jpa java-testing jpa-testing junit

Java Cucumber testing

Make a product directory with bin/ and lib/ directories within.

You need the cucumber-jvm (https://github.com/cucumber/cucumber-jvm) libs in the lib/ folder. You need:

* cucumber-core-1.1.1.jar  
* cucumber-html-0.2.2.jar  
* cucumber-java-1.1.1.jar  
* cucumber-junit-1.1.1.jar  
* junit-4.11.jar

I got these via Apache Ant. You can use Maven, or the Ant build script that comes with the hello world example in the cucumber-jvm repository.

Next you need to write the features file. Put this in the main directory:

 Feature: Hello World

  Scenario: Print my shopping list
    The list should be printed in alphabetical order of the item names

    Given a shopping list:
      | name  | count |
      | Milk  |     2 |
      | Cocoa |     1 |
      | Soap  |     5 |
    When I print that list
    Then it should look like:
      """
      1 Cocoa
      2 Milk
      5 Soap

      """

The lines starting Given, When and Then are parsed by Cucumber. You need to write step definitions for these. Create a file called ShoppingStepdefs.java in your main folder:

 import cucumber.api.java.en.Given;
 import cucumber.api.java.en.Then;
 import cucumber.api.java.en.When;

 import java.util.List;

 import static org.junit.Assert.assertEquals;

 public class ShoppingStepdefs {
    private StringBuilder printedList; 
    private final ShoppingList shoppingList = new ShoppingList();

The above line initialises the class we’ll be testing (to be defined later).

  public static class ShoppingItem {
      private String name;
      private Integer count;
  }

This is used for grabbing list data. See below.

  @Given("^a shopping list:$")
  public void a_shopping_list(List<ShoppingItem> items) throws Throwable {
      for (ShoppingItem item : items) {
          shoppingList.addItem(item.name, item.count);
      }
  }

This defines the Given line above, the one with ‘a shopping list’ as its text. The “:” means we’ll be taking in an object. “^” and “$” end the definition.

We take in the | Milk | 2 | in the feature file as a List as a parameter. Then in the method we go through each adding it to the shoppingList initialised earlier.

  @When("^I print that list$")
  public void I_print_that_list() throws Throwable {
      printedList = new StringBuilder();
      shoppingList.print(printedList);
  }

Then we define the ‘When’ line. This simply takes the output of the shoppingList and puts it the printedList StringBuilder as defined above.

  @Then("^it should look like:$")
  public void it_should_look_like(String expected) throws Throwable {
      assertEquals(expected, printedList.toString());
  }

Then final ‘Then’ statement takes in a string as a parameter and compares it to the output of the printedList.

 }

Now we need the ShoppingList class. Put it in the root folder:

 import java.io.IOException;
 import java.util.Map;
 import java.util.SortedMap;
 import java.util.TreeMap;

 public class ShoppingList {
    private SortedMap<String,Integer> items = new TreeMap<String, Integer>();

    public void addItem(String name, Integer count) {
        items.put(name, count);
    }

    public void print(Appendable out) throws IOException {
        for (Map.Entry<String, Integer> entry : items.entrySet()) {
            out.append(entry.getValue().toString()).append(" ").append(entry.getKey()).append("\n");
        }
    }
 }

Now you need a build.xml file to run the tests via ant (I’ve omitted things like clean for clarity):

 <project name="java-helloworld" basedir="." default="runcukes">

    <property name="jars" value="lib"/>

    <target name="classpath">
        <path id="classpath">
            <fileset dir="${jars}">
                <include name="**/*.jar"/>
            </fileset>
            <pathelement location="bin/classes"/>
        </path>
    </target>

    <target name="compile" depends="classpath">
        <mkdir dir="bin/classes"/>
        <javac srcdir="." destdir="bin/classes" classpathref="classpath" includeantruntime="false"/>
    </target>

The above just compiles the java files into classes and sets the classpath.

    <target name="runcukes" depends="compile">
        <mkdir dir="bin/cucumber-junit-report"/>
        <java classname="cucumber.api.cli.Main" fork="true" failonerror="false" resultproperty="cucumber.exitstatus">
            <classpath refid="classpath"/>
            <arg value="--format"/>
            <arg value="junit:bin/cucumber-junit-report/allcukes.xml"/>
            <arg value="--format"/>
            <arg value="pretty"/>
            <arg value="--format"/>
            <arg value="html:bin/cucumber-html-report"/>
            <arg value="--glue"/>
            <arg value=""/>
            <arg value="."/>
        </java>

This runs the cucumber tests via running cucumber.api.cli.Main with various arguements that point to the location of our feature file and sets various reporting and formatting features.

      <junitreport todir="bin/cucumber-junit-report">
          <fileset dir="bin/cucumber-junit-report">
              <include name="allcukes.xml"/>
          </fileset>
          <report format="frames" todir="bin/cucumber-junit-report"/>
      </junitreport>

This next part runs junit on the junit that cucumber produced, failing if we have errors. The hello-world sample project has a fail tag here, but I haven’t found it to be needed, so I’ve omitted it here.

    </target>

 </project>

Now run ‘ant’ in the directory and voila:

 runcukes:
     [java] Feature: Hello World
     [java] 
     [java]   Scenario: Print my shopping list # helloworld.feature:3
     [java]     The list should be printed in alphabetical order of the item names
     [java] 
     [java]     Given a shopping list:         # ShoppingStepdefs.a_shopping_list(List<ShoppingStepdefs$ShoppingItem>)
     [java]     When I print that list         # ShoppingStepdefs.I_print_that_list()
     [java]     Then it should look like:      # ShoppingStepdefs.it_should_look_like(String)
     [java]       """
     [java]       1 Cocoa
     [java]       2 Milk
     [java]       5 Soap
     [java] 
     [java]     Then it should look like:      # ShoppingStepdefs.it_should_look_like(String)
     [java]       """
     [java]       1 Cocoa
     [java]       2 Milk
     [java]       5 Soap
     [java] 
     [java]       """
     [java] 

You’ll see errors in this output should there be a failure.

java ant java-testing cucumber

Page 1 of 1