When writing test cases for end-to-end test scenarios using java, selenium, java; we can keep common steps into the base class method and specific add, edit steps in the specific class.
public abstract class XXXXBaseTest extends SeleniumTest {
#Test
public void validateCalendarUi() throws IOException {
**ExpCalendar expCalendar = openExpCalendar();**
String calenderAvailable = expCalendar.getHeaderViewText();
Assert.assertEquals(calenderAvailable, "Calendar View", "Failed : Calendar is not available");
}
}
Then, opened calendar() method is overridden in each specific class with specific steps.
public class XXXXXViewExpirationCalendarTest extends RefDataExpirationCalendarTest {
#Override
protected ExpCalendar openExpCalendar() {
//Here write specific methods
}
}
Is this appropriate approach for test scripting? Can we use inheritance concept to write test cases in this way?
So lets assume I am having the following stuff defined:
public interface IExportTool {
void export(IReport iReport);
}
And then attempting to use it:
public class KibanaExporter implements IExportTool{
public void export(IReport kibana) {
kibana = (Kibana) kibana;
((Kibana) kibana).toJSON();
}
}
But there are also other classes which would again be doing something like that too:
public class MetricExporter implements IExportTool{
public void export(IReport metric) {
metric = (Metric) metric;
((Metric) metric).toJSON(); // might be something else here like toXML etc
}
}
Please note that both Kibana and Metric are implementing IReport<KibanaRow> and IReport<MetricRow> respectively, while the IReport interface looks like:
public interface IReport<T> {
void addRow(T row);
}
I don't like all this casting, this doesn't feel right nor gives me autocomplete, so any suggestion how to do it properly?
From what you've posted, it's clear that both Kibana and Metric are subtypes of IReport.
In that case, you can make the interface generic:
interface IExportTool<R extends IReport> {
void export(R iReport);
}
And then change the implementations in this fashion:
public class KibanaExporter implements IExportTool<Kibana>{
public void export(Kibana kibana) {
kibana.toJSON();
}
}
And:
public class MetricExporter implements IExportTool<Metric> {
public void export(Metric metric) {
metric.toJSON();
}
}
This version allows the compiler to understand and validate that only instances of subtypes of IReport will ever be passed to export(). Code using this will be validated by the compiler, such that MetricExporter().export() can only be called with an object of type Metric and KibanaExporter().export() with an object of type Kibana.
And with that, type casts are no longer needed.
Most of my classes have different behavior if they are client or server side. (client: gui, server: connection stuff) but they also have some common behavior. I want to know what's the best way to do this.
Example content of a class:
public class Example{
private void commonMethod(){
//common code
}
public void clientMethod(){
commonMethod()
//Client code
}
public void serverMethod(){
commonMethod()
//Server code
}
}
What i want:
1 method with some way to specify client or server
Readable code
What is allowed:
still have 3 private methods : server, common and client
What i want to avoid:
case (unless it is readable / short)
if
Things i was thinking of:
enums (to specify client and server) and a case (better then to use meaningless ints or booleans)
annotations (#clientside) (#serverside)
Edit:
My classes are loaded in by an api, an example client/server method would be init. so in my main class i need to run that method for all the classes that need initialization.
If I were you (and if I understand your needs) I would use a common interface implemented by a client and a server class, with an abstract class in the middle:
public interface Example {
public void method();
}
public abstract class AbstractExample implements Example {
#Override
public void method() {
common();
implMethod();
}
private void common() {
// common implementation
}
protected abstract void implMethod();
}
public class ExampleClientImpl extends AbstractExample {
#Override
protected void implMethod() {
// client implementation
}
}
public class ExampleServerImpl extends AbstractExample {
#Override
protected void implMethod() {
// server implementation
}
}
With this approach you can also split your classes in common/client/server packages or better modules.
Is it possible using AspectJ to find a list of all Classes which implement a certain interface. For e.g I have an interface MatchRule. Then I can have classes DefaultMatchRule and CustomMatchRule concrete clases which implement MatchRule interface.
Now at runtime I want to get a list which will have 2 classes DefaultMatchRule and CustomMatchRule
public interface MatchRule {
}
public class DefaultMatchRule implements MatchRule {
}
public class CustomMatchRule implements MatchRule {
}
public aspect FindSubClasses {
// some thing to find list of classes implementing MatchRule interface
}
AspectJ is not designed to finding classes. Your best option is to scan the classpath and use reflection.
If you can live with compile-time information, the Eclipse AJDT plugin offers good graphical information for all AspectJ advises.
But if you can live with some limitations, you can find the classes for all objects that is advised by AspectJ.
A solution that prints out the class names for all objects of classes that implements MatchRule:
#Aspect
public class FindSubClassesAspect {
#Pointcut("execution(demo.MatchRule+.new(..))")
public void demoPointcut() {
}
#After("demoPointcut()")
public void afterDemoPointcut(
JoinPoint joinPoint) {
FindSubClasses.addMatchRuleImplememtation(
joinPoint.getTarget().getClass().getSimpleName());
}
}
A class that contain the information about all the MatchRule implementations:
public enum FindSubClasses {
;
private static Set<String> matchRuleImplementations =
new HashSet<String>();
public static void addMatchRuleImplememtation(String className) {
matchRuleImplementations.add(className);
}
public static Collection<String> getMatchRuleImplementations() {
return matchRuleImplementations;
}
}
A simple driver that demonstrate that the aspect works:
public class Driver {
public static void main(String[] args) {
new DefaultMatchRule();
new CustomMatchRule();
Collection<String> matchRuleImplementations =
FindSubClasses.getMatchRuleImplementations();
System.out.print("Clases that implements MatchRule: ");
for (String className : matchRuleImplementations) {
System.out.print(className + ", ");
}
}
}
The output of executing this driver:
Clases that implements MatchRule: DefaultMatchRule, CustomMatchRule,
I hope this helps!
The only possible way to do this at runtime is probably scanning all your packages and checking to see whether your classes implement that interface.
I can't think of any other way this is possible. In fact, Eclipse has a context menu option that shows the "Implementors" of an interface but they achieve that by scanning the packages.
What is the best way to write junit tests for interfaces so they can be used for the concrete implementing classes?
e.g. You have this interface and implementing classes:
public interface MyInterface {
/** Return the given value. */
public boolean myMethod(boolean retVal);
}
public class MyClass1 implements MyInterface {
public boolean myMethod(boolean retVal) {
return retVal;
}
}
public class MyClass2 implements MyInterface {
public boolean myMethod(boolean retVal) {
return retVal;
}
}
How would you write a test against the interface so you can use it for the class?
Possibility 1:
public abstract class MyInterfaceTest {
public abstract MyInterface createInstance();
#Test
public final void testMyMethod_True() {
MyInterface instance = createInstance();
assertTrue(instance.myMethod(true));
}
#Test
public final void testMyMethod_False() {
MyInterface instance = createInstance();
assertFalse(instance.myMethod(false));
}
}
public class MyClass1Test extends MyInterfaceTest {
public MyInterface createInstance() {
return new MyClass1();
}
}
public class MyClass2Test extends MyInterfaceTest {
public MyInterface createInstance() {
return new MyClass2();
}
}
Pro:
Need only one method to be implemented
Con:
Dependencies and mock objects of class under test have to be the same for all tests
Possibility 2:
public abstract class MyInterfaceTest
public void testMyMethod_True(MyInterface instance) {
assertTrue(instance.myMethod(true));
}
public void testMyMethod_False(MyInterface instance) {
assertFalse(instance.myMethod(false));
}
}
public class MyClass1Test extends MyInterfaceTest {
#Test
public void testMyMethod_True() {
MyClass1 instance = new MyClass1();
super.testMyMethod_True(instance);
}
#Test
public void testMyMethod_False() {
MyClass1 instance = new MyClass1();
super.testMyMethod_False(instance);
}
}
public class MyClass2Test extends MyInterfaceTest {
#Test
public void testMyMethod_True() {
MyClass1 instance = new MyClass2();
super.testMyMethod_True(instance);
}
#Test
public void testMyMethod_False() {
MyClass1 instance = new MyClass2();
super.testMyMethod_False(instance);
}
}
Pro:
fine granualtion for each test including dependencies and mock objects
Con:
Each implementing test class requires to write additional test methods
Which possibility would you prefer or what other way do you use?
Contrary to the much-voted-up answer that #dlev gave, it can sometimes be very useful/needful to write a test like you're suggesting. The public API of a class, as expressed through its interface, is the most important thing to test. That being said, I would use neither of the approaches you mentioned, but a Parameterized test instead, where the parameters are the implementations to be tested:
#RunWith(Parameterized.class)
public class InterfaceTesting {
public MyInterface myInterface;
public InterfaceTesting(MyInterface myInterface) {
this.myInterface = myInterface;
}
#Test
public final void testMyMethod_True() {
assertTrue(myInterface.myMethod(true));
}
#Test
public final void testMyMethod_False() {
assertFalse(myInterface.myMethod(false));
}
#Parameterized.Parameters
public static Collection<Object[]> instancesToTest() {
return Arrays.asList(
new Object[]{new MyClass1()},
new Object[]{new MyClass2()}
);
}
}
I strongly disagree with #dlev. Very often it is a very good practice writing tests that use interfaces. Interface defines contract between client and the implementation. Very often all your implementations must pass exactly the same tests. Obviously each implementation can have its own tests.
So, I know 2 solutions.
Implement abstract test case with various tests that use interface. Declare abstract protected method that returns concrete instance. Now inherit this abstract class as many times as you need for each implementation of your interface and implement the mentioned factory method accordingly. You can add more specific tests here as well.
Use test suites.
I disagree with dlev as well, there's nothing wrong with writing your tests against interfaces instead of concrete implementations.
You probably want to use parameterized tests. Here is what it would look like with TestNG, it's a little more contrived with JUnit (since you can't pass parameters directly to test functions):
#DataProvider
public Object[][] dp() {
return new Object[][] {
new Object[] { new MyImpl1() },
new Object[] { new MyImpl2() },
}
}
#Test(dataProvider = "dp")
public void f(MyInterface itf) {
// will be called, with a different implementation each time
}
Late addition to the subject, sharing newer solution insights
I'm also looking for a proper and efficient way of testing (based on JUnit) correctness of multiple implementations of some interfaces and abstract classes. Unfortunately, neither JUnit's #Parameterized tests nor TestNG's equivalent concept correctly fits my requirements, since I don't know a priori the list of implementations of these interface/abstract classes that might exists. That is, new implementations might be developped, and testers might not have access to all existing implementations; it is therefore not efficient to have test classes specify the list of implementation classes.
At this point, I have found the following project which seems to offer a complete and efficient solution to simplify this type of tests: https://github.com/Claudenw/junit-contracts . It basically allows the definition of "Contract Tests", through the annotation #Contract(InterfaceClass.class) on contract test classes. Then an implementer would create an implementation specific test class, with annotations #RunWith(ContractSuite.class) and #ContractImpl(value = ImplementationClass.class); the engine shall automatically apply any contract test that applies to ImplementationClass, by looking for all Contract Test defined for any interface or abstract class from which ImplementationClass derives. I have not yet tested this solution, but this sounds promising.
I have also found the following library: http://www.jqno.nl/equalsverifier/ . This one satisfies a similar though much more specific need, which is asserting a class conformity specifically to Object.equals and Object.hashcode contracts.
Similarly, https://bitbucket.org/chas678/testhelpers/src demonstrate a strategy to validate some Java fondamental contracts, including Object.equals, Object.hashcode, Comparable.compare, Serializable. This project use simple test structures, which, I believe, can be easily reproduced to suite any specific needs.
Well, that's it for now; I'll keep this post updated with other usefull informations I may find.
I would generally avoid writing unit tests against an interface, for the simple reason that an interface, however much you would like it to, does not define functionality. It encumbers its implementors with syntactic requirements, but that's it.
Unit tests, conversely, are intended to ensure that the functionality you expect is present in a given code path.
That being said, there are situations where this type of test could make sense. Assuming you wanted these tests to ensure that classes you wrote (that share a given interface) do, in fact, share the same functionality, then I would prefer your first option. It makes it easiest on the implementing subclasses to inject themselves into the testing process. Also, I don't think your "con" is really true. There's no reason you can't have the classes actually under test provide their own mocks (though I think that if you really need different mocks, then that suggests your interface tests aren't uniform anyway.)
with java 8 i do this
public interface MyInterfaceTest {
public MyInterface createInstance();
#Test
default void testMyMethod_True() {
MyInterface instance = createInstance();
assertTrue(instance.myMethod(true));
}
#Test
default void testMyMethod_False() {
MyInterface instance = createInstance();
assertFalse(instance.myMethod(false));
}
}
public class MyClass1Test implements MyInterfaceTest {
public MyInterface createInstance() {
return new MyClass1();
}
}
public class MyClass2Test implements MyInterfaceTest {
public MyInterface createInstance() {
return new MyClass2();
}
#Disabled
#Override
#Test
public void testMyMethod_True() {
MyInterfaceTest.super.testMyMethod_True();
};
}