org.easetech.easytest.runner
Class DataDrivenTestRunner.EasyTestRunner

java.lang.Object
  extended by org.junit.runner.Runner
      extended by org.junit.runners.ParentRunner<org.junit.runners.model.FrameworkMethod>
          extended by org.junit.runners.BlockJUnit4ClassRunner
              extended by org.easetech.easytest.runner.DataDrivenTestRunner.EasyTestRunner
All Implemented Interfaces:
org.junit.runner.Describable, org.junit.runner.manipulation.Filterable, org.junit.runner.manipulation.Sortable
Enclosing class:
DataDrivenTestRunner

public class DataDrivenTestRunner.EasyTestRunner
extends org.junit.runners.BlockJUnit4ClassRunner

A BlockJUnit4ClassRunner Runner implementation that adds support of input parameters as part of the Test annotation. This BlockJUnit4ClassRunner extension is modified for providing convenient Data Driven Testing support to its users. This Runner is capable of generating new instances of FrameworkMethod based on the test data for a given method. For eg. If there is a method "testMethod(String testData)" that has three sets of test data : [{"testData1"},{"testData2"},{"testData3"}], then this runner will generate three FrameworkMethod instances with the method names :
testMethod{testData1}
testMethod{testData2}
and
testMethod{testData3}


A user can specify the test data at the class level(and/or method level), using the DataLoader annotation and(if wants) override it at the method level. The Runner will take care of executing the test method with the right test data.
This is extremely beneficial in cases, where the user just wants to load the data once and then reuse it for all the test methods. If the user wants, then he can always override the test data at the method level by specifying the DataLoader annotation at the method level.

In addition, this runner also introduces a new way for the user to specify the test data using DataLoader annotation.

There is also a Param annotation to handle boiler plate tasks on behalf of the user as well as supports additional functionality that eases the life of the user. For eg. it supports Java PropertyEditors to automatically convert a String to the specified Object. It also supports passing a Map to the test method that contains all the available test data key / value pairs for easy consumption by the user. It also supports user defined custom Objects as parameters.Look at Converter for details.

Finally, EasyTest also supports Intercept annotation. This annotation can be used to intercept calls to the test subject that is currently being tested. For eg. if you want to capture how much time a particular method of the actual service class is taking, then you can mark the field representing the testSubject with Intercept annotation. The framework also provides convenient way to write your own custom method interceptors.

Author:
Anuj Kumar

Constructor Summary
DataDrivenTestRunner.EasyTestRunner(Class<?> klass)
          Construct a new DataDrivenTestRunner.
 
Method Summary
protected  void collectInitializationErrors(List<Throwable> errors)
          Try to collect any initialization errors, if any.
protected  List<org.junit.runners.model.FrameworkMethod> computeTestMethods()
          Overridden the compute test method to make it save the method list as class instance, so that the method does not run multiple times.
protected  ClassLoader determineClassLoader(Class<?> fieldType, Class<?> testClass)
          Determine the right class loader to use to load the class
protected  void instrumentClass(Class<?> testClass)
          Instrument the class's field that are marked with Intercept annotation
 org.junit.runners.model.Statement methodBlock(org.junit.runners.model.FrameworkMethod method)
          Override the methodBlock to return custom ParamAnchor
protected  String testName(org.junit.runners.model.FrameworkMethod method)
          Override the name of the test.
protected  void validateConstructor(List<Throwable> errors)
          Validate that there could ever be only one constructor.
protected  void validateTestMethods(List<Throwable> errors)
          Validate the test methods.
protected  org.junit.runners.model.Statement withAfterClasses(org.junit.runners.model.Statement statement)
          Returns a Statement: run all non-overridden @AfterClass methods on this class and superclasses before executing statement; all AfterClass methods are always executed: exceptions thrown by previous steps are combined, if necessary, with exceptions from AfterClass methods into a MultipleFailureException.
 
Methods inherited from class org.junit.runners.BlockJUnit4ClassRunner
createTest, describeChild, getChildren, getTestRules, methodInvoker, possiblyExpectingExceptions, rules, runChild, validateInstanceMethods, validateNoNonStaticInnerClass, validateOnlyOneConstructor, validateZeroArgConstructor, withAfters, withBefores, withPotentialTimeout
 
Methods inherited from class org.junit.runners.ParentRunner
childrenInvoker, classBlock, classRules, filter, getDescription, getName, getRunnerAnnotations, getTestClass, run, runLeaf, setScheduler, sort, validatePublicVoidNoArgMethods, withBeforeClasses
 
Methods inherited from class org.junit.runner.Runner
testCount
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

DataDrivenTestRunner.EasyTestRunner

public DataDrivenTestRunner.EasyTestRunner(Class<?> klass)
                                    throws org.junit.runners.model.InitializationError
Construct a new DataDrivenTestRunner. We first inject the TestBeans, if any is specified by the user using Provided annotation. Note that Provided annotation works, iff tha user has provided TestConfigProvider annotation at the class level with a valid TestConfig class that has public methods marked with TestBean annotation. Next, we try instrument the fields that are marked with Intercept annotation. Finally, we instantiate the container for report generation logic, if the user has provided Report annotation at the class level.

Parameters:
klass - the test class whose test methods needs to be executed
Throws:
org.junit.runners.model.InitializationError - if any error occurs
Method Detail

instrumentClass

protected void instrumentClass(Class<?> testClass)
                        throws IllegalArgumentException,
                               IllegalAccessException,
                               InstantiationException
Instrument the class's field that are marked with Intercept annotation

Parameters:
testClass - the class under test
Throws:
IllegalArgumentException - if an exception occurred
IllegalAccessException - if an exception occurred
InstantiationException - if an exception occurred

determineClassLoader

protected ClassLoader determineClassLoader(Class<?> fieldType,
                                           Class<?> testClass)
Determine the right class loader to use to load the class

Parameters:
fieldType -
testClass -
Returns:
the classLoader or null if none found

collectInitializationErrors

protected void collectInitializationErrors(List<Throwable> errors)
Try to collect any initialization errors, if any.

Overrides:
collectInitializationErrors in class org.junit.runners.BlockJUnit4ClassRunner
Parameters:
errors -

testName

protected String testName(org.junit.runners.model.FrameworkMethod method)
Override the name of the test. In case of EasyTest, it will be the name of the test method concatenated with the input test data that the method will run with.

Overrides:
testName in class org.junit.runners.BlockJUnit4ClassRunner
Parameters:
method - the FrameworkMethod
Returns:
an overridden test method Name

computeTestMethods

protected List<org.junit.runners.model.FrameworkMethod> computeTestMethods()
Overridden the compute test method to make it save the method list as class instance, so that the method does not run multiple times. Also, this method now is responsible for creating multiple FrameworkMethod instances for a given method with multiple test data. So, if a given test method needs to run three times with three set of input test data, then this method will actually create three instances of FrameworkMethod. In order to allow the user to override the default name, FrameworkMethod is extended with EasyFrameworkMethod and EasyFrameworkMethod.setName(String) method introduced.

Overrides:
computeTestMethods in class org.junit.runners.BlockJUnit4ClassRunner
Returns:
list of FrameworkMethod

validateConstructor

protected void validateConstructor(List<Throwable> errors)
Validate that there could ever be only one constructor.

Overrides:
validateConstructor in class org.junit.runners.BlockJUnit4ClassRunner
Parameters:
errors - list of any errors while validating the Constructor

validateTestMethods

protected void validateTestMethods(List<Throwable> errors)
Validate the test methods.

Overrides:
validateTestMethods in class org.junit.runners.BlockJUnit4ClassRunner
Parameters:
errors - list of any errors while validating test method

methodBlock

public org.junit.runners.model.Statement methodBlock(org.junit.runners.model.FrameworkMethod method)
Override the methodBlock to return custom ParamAnchor

Overrides:
methodBlock in class org.junit.runners.BlockJUnit4ClassRunner
Parameters:
method - the Framework Method
Returns:
a compiled Statement object to be evaluated

withAfterClasses

protected org.junit.runners.model.Statement withAfterClasses(org.junit.runners.model.Statement statement)
Returns a Statement: run all non-overridden @AfterClass methods on this class and superclasses before executing statement; all AfterClass methods are always executed: exceptions thrown by previous steps are combined, if necessary, with exceptions from AfterClass methods into a MultipleFailureException. This method is also responsible for writing the data to the output file in case the user is returning test data from the test method. This method will make sure that the data is written to the output file once after the Runner has completed and not for every instance of the test method.

Overrides:
withAfterClasses in class org.junit.runners.ParentRunner<org.junit.runners.model.FrameworkMethod>


Copyright © 2013. All Rights Reserved.