Version 4

    This article will show you how to write database related tests with JBoss RedDeer.

     

    In this article we shall mainly focus to these areas:

    • Database Drivers definitions
    • Database Profiles
    • Database Requirements

    Prerequisites

    Database

    Outside IDE download and start database needed for this tutorial. We will use sakila database running on h2 database. Follow these steps:

    mkdir ~/db

    cd db

    git://github.com/maxandersen/sakila-h2.git./sakila-h2/runh2.sh

    You should see a database started


     

    Eclipse


    It’s expected you have JDK 1.6 or higher and Eclipse Juno or Kepler. I’ll use JBoss Developer studio 8.0.0.Beta1 which is based on Eclipse and can be used as well for purpose of this tutorial and provides plenty of features outside basic Eclipse distribution. You can download it from https://www.jboss.org/products/devstudio.html

    and to install is simply using following command:


    java -jar jbdevstudio-product-universal-8.0.0.Beta1-v20140408-2350-B93.jar


    Go through installer wizard and after it’s finish start JBoss Developer Studio, select new workspace location and you should see a screen below .


    Click on “Get started with JBoss Central” and your IDE is ready for you.

     


    JBoss RedDeer


    JBoss Reddeer is a framework for UI (functional) testing in Eclipse based environment. You can find its resources here https://github.com/jboss-reddeer/reddeer/wiki


    First we need to install JBoss RedDeer. For purpose of this tutorial I’ll use development version 0.6.0-SNAPSHOT located at master update site: http://download.jboss.org/jbosstools/builds/staging/RedDeer_master/all/repo/


    To install RedDeer go to Help -> Install New Software..., click Add... and RedDeer update site into Location field.



    Then we click OK and Select All (for simplicity), specificaly we need only RedDeer Eclipse and RedDeer requirement and their dependencies. I’ll not go through Eclipse plug-ins installation since it’s very easy process containing just few Next, Finish and Restart click. When this is done you’ll see empty workspace but with all RedDeer features installed.


    Create test plugin


    We need to create a test plug-in first. Simply we can use New RedDeer Test Plug-in wizard. We will fill in plugin name, id (for example org.jboss.reddeer.tutorial.database) and vendor (whatever) and click Finish.


     


    First we shall try if everything is ok and RedDeer facility works as expected. Select project in Package Explorer and Go to menu and click Run -> Run As -> RedDeer Test. You shoud see similar error like this one.



    That’s Ok. We don’t have any test defined yet. Let’s create one. We can use JUnit Test Wizard. From main menu select File -> New ->Other… -> JUnit Test Case


    Let’s put name of the test, for example DatabaseTest and click Finish.


     


    Now we can try run from the previous step. New JBDS windows should occur for a while and we should see JUnit View containing this whis is Ok based on the default test definition.

     


    One more thing we need to do but only if we’re using JBDS. When running test we need to disable usage reporting that it would block our test execution. It didn’t now because we did no UI action but it would definitely in the future. We simply need to disable it by adding

    -Dusage_reporting_enabled=false into Run Configurations (Run -> Run Configurations…)



    Congratulations, if you’re here you did all the the prerequisites actions. Let’s start some some more serious stuff.

    To have working Database Connection Profile we need to create a Driver Definition if we don’t have one. For this we can use DriverDefinitionWizard accessible from DriverDefinitionPreferencePage using DriverDefinition class.


    Adding missing dependencies


    We will utilize several RedDeer plug-ins which were not added into dependencies set for our testplugin by default. To fix that just open META-INF/MANIFEST.MF file under our test project. Click on Required-Plug-ins tab and add:

    • org.jboss.reddeer.jface
    • org.jboss.reddeer.workbench
    • org.jboss.reddeer.requirement

     

    Then save the file. First two are needed for work with Driver Definitions and Connection Profiles and last one is needed for Database requirement support. You should see something like picture below. Save the file.



    Creating Driver Definition


    First  we tell JUnit we wan to run our test with RedDeer runner. This enables many features of RedDeer which we don’t need necessarily right now but we will need them later (like Requirements support). Do it by adding RedDeerSuite as a test Runner.


    Let’s create driver definition operation in your test. This snippet of code will create Generic H2 profile. Just open DatabaseTest.java and paste green part of code. We will explain this later.


    @RunWith(RedDeerSuite.class)

    class DatabaseTest {

     

    @Test

    public void test {

    final String DRIVER_NAME = "Test H2 Driver";      

     

    // Driver template

    DriverTemplate dt = new DriverTemplate("Generic JDBC Driver", "1.0");          

     

    // Driver definition      

    DriverDefinition dd = new DriverDefinition();

    dd.setDriverClass("org.h2.Driver");

    dd.setDriverLibrary("/opt/sakila-h2/h2-1.3.161.jar");

    dd.setDriverName(DRIVER_NAME);

    dd.setDriverTemplate(dt);

     

    // Driver Definition creation

    DriverDefinitionPreferencePage preferencePage = new DriverDefinitionPreferencePage();

    preferencePage.open();

    DriverDefinitionWizard ddw = preferencePage.addDriverDefinition();

    DriverDefinitionPage page = new DriverDefinitionPage();

    page.selectDriverTemplate(dt.getType(),dt.getVersion());

    page.setName(DRIVER_NAME);

    page.addDriverLibrary(dd.getDriverLibrary());

    page.setDriverClass("org.h2.Driver");

    ddw.finish();

    preferencePage.ok();

    }


    We created and filled classes corresponding to UI model of Driver Definition Wizard.  In creation section we used DriverDefinitionPreferencePage, resp. Wizard and passed desired values. Note to have it running we need to have h2 driver available at /opt/sakila-h2/h2-1.3.161.jar". Only thing we need to fix are imports. Ctrl+Shift+O should do that.


    Now you can run your tests the same way you did with empty test a while before. You should see UI actions performed by RedDeer and after after tested IDE is closed green JUnit Report



    Creating Connection Profile


    Once we have prepared Driver Definition we can create database connection profile. For simplicity let’s add following code after existing one into the same test.


    // Database profile

    DatabaseProfile dbProfile = new DatabaseProfile();

    dbProfile.setDatabase("sakila");

    dbProfile.setDriverDefinition(dd);

    dbProfile.setHostname("jdbc:h2:tcp://localhost/sakila");    // URL

    dbProfile.setName("myDBProfile");

    dbProfile.setPassword("");

    dbProfile.setPort("8082");

    dbProfile.setUsername("sa");

    dbProfile.setVendor("Generic JDBC");


    Now we can simply create Database profile.

     

    ConnectionProfileWizard cpw = new ConnectionProfileWizard();
    cpw.open();
    cpw.createDatabaseProfile(databaseProfile);

     

    Code above needs no special explanation. Just note we are using DatabaseProfile entity as a  model class and ConnectionProfileWizard as the UI controller. Again add auto-imports and you should see no errors. If you have any troubles, see that all API used for database support in this section comes from org.jboss.reddeer.eclipse.datatools.ui package

    .

    Configuration from outside sources


    Now we were able to create Connection Profile. We usually don’t want to hardcode information like connection details. Let’s rather see if RedDeer can help us to use connection data from some external file or even multiple database configuration from several of them. That’s where RedDeer requirements fit very well.


    RedDeer provides pre-created Database Requirement Extension that could simply provide this.There are just few things that user must do:

    • create configuration file (files)
    • annotate testclass with @Database annotation
    • inject requirement class containing configuration
    • point ReddDer framework to configuration location by using @InjectRequirement
    • use configuration data by defining requirement location

     

    Create xml configuration file


    Create db.xml (or any other name you want) file that follows RedDeerSchema.xsd schema definition. Put it under /opt/db-req/ .


    <?xml version="1.0" encoding="UTF-8"?>

    <testrun xmlns="http://www.jboss.org/NS/Req" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

    xmlns:db="http://www.jboss.org/NS/db-schema"

    xsi:schemaLocation="http://www.jboss.org/NS/Req http://www.jboss.org/schema/reddeer/RedDeerSchema.xsd                             http://www.jboss.org/NS/db-schema http://www.jboss.org/schema/reddeer/DatabaseRequirement.xsd">

        <requirements>

            <db:database-requirement name="h2-sakila">

                <db:driverName>My H2 Driver</db:driverName>

                <db:driverType>Generic JDBC</db:driverType>

                <db:driverTypeVersion>1.0</db:driverTypeVersion>

                <db:driverPath>/opt/sakila-db/h2-1.3.161.jar</db:driverPath>

                <db:driverClass>org.h2.Driver</db:driverClass>

                <db:profileName>dbProfile</db:profileName>

                <db:jdbcString>jdbc:h2:db://localhost/sakila</db:jdbcString>

                <db:username>sa</db:username>

                <db:password></db:password>

            </db:database-requirement>

        </requirements>

    </testrun>

     

    Add RedDeer config into Run Configuration (same steps as for Usage reporting)


    Annotate test class with @Database


    Now we add @Database annotation that tells to RedDeer that our test will use Database requirement.  Note that @Database comes from org.jboss.reddeer.requirements.db.DatabaseRequirement package.


    @Database(name="dbtest")

    @RunWith(RedDeerSuite.class)

    class MyDBTest {

     

    @Test

    public void testMyH2Database {

     

    Name parameter has currently no meaning except it can help us to search for log to check if requirement was processed. If we run test now we should see debug message confirming RedDeer detected our requirement.


    DEBUG [WorkbenchTestable][DatabaseRequirement] Requirement name:dbtest


    Inject database configuration


    RedDeer provides simple injecting mechanism for obtaining requirement instance. For it we will use @InjectRequirement annotation.


    class MyDBTest {

         @InjectRequirement

         DatabaseRequirement dbRequirement;


    @Test

    public void testMyH2Database {

    DatabaseConfiguration cfg = dbRequirement.getConfiguration();

     

    Now we have an access to a external database configuration with RedDeer Requirements extensions. We can simply change our hard-coded values to values from configuration instance.

     

    // Driver template

    DriverTemplate dt = new DriverTemplate(cfg.getDriverType(),cfg.getDriverTypeVersion());          

     

    // Driver definition      

    DriverDefinition dd = new DriverDefinition();

    dd.setDriverClass(cfg.getDriverClass());

    dd.setDriverLibrary(cfg.getDriverPath());

    dd.setDriverName(cfg.getDriverName());

    dd.setDriverTemplate(dt);

     

    And similarly update for connection profiles.

    dbProfile.setDatabase(cfg.getProfileName());

    dbProfile.setDriverDefinition(dd);

    dbProfile.setHostname(cfg.getJDBCString());

    dbProfile.setName(cfg.getProfileName());

    dbProfile.setPassword(cfg.getPassword());

    dbProfile.setUsername(cfg.getUsername());

    dbProfile.setVendor(cfg.getDriverType());


    Now we should be able to execute our test with configuration that is taken from external definition. We can even take define multiple database requirement definitions and tests will be executed for each of them as they are parametrized. That’s where RedDeer JUnit facility comes to help.


    To summarize there are these advantages of using Database requirements:

    • database parameter values are not hardcoded or not located inside the test classes
    • requirement xml file has its xsd template so we can use features like code completion and validation
    • we can simply inject configuration into any test
    • we can use multiple definitions for multiple test execution against different databases

     

    That’s it for now. Note that this is just experimental API and some construction are little bit clumsy in some cases and it may change the future. But as you can see you can use it to test your own plug-ins that consumes database informations.  Also note that not all database types are currently supported. But it should give you quite good overview about how things around databases can be handled in JBoss RedDeer.To find out more about RedDeer, requirements and other features, see https://github.com/jboss-reddeer/reddeer/wiki/User-Guide