Currently I have one java class (Step Definitions.java) that contains all -
#Before, #After, #Given, #When, #Then
I want to split these annotations into three different classes. One class for the #Before / #After. One class for #Given; One class for #When; and One class for #Then.
All 4 classes will be under the same package. Can this be done? Do I have to change anything in the runner class? Any other references I have to make to these seperate classes? or should this just work like that, when I call the Gherkin in my feature file?!
It will work out off the box. As long as the code is mentioned in the package structure given to the glue option for cucumberoptions, it will be loaded and executed. All the stepdefinition and hook code are loaded for each scenario, so doesnt matter which class the code exists.
Though better would be to separate them according to parts of the application they deal with.
Related
Ok selenium gurus a bit of an open question here. I am looking for some guidance on the best way to organize my tests that use object oriented principles.
At the moment I am creating a testrunner main class from which I create an object of a general test class. I am then extending this class for more granular tests.
An example.
I need to open the browser, enter the url, log in as a user.
From there you can access perhaps 40 different links each containing their own pieces of functionality. E.g. A profile link which leads to a profiule screen where you can enter introduction text, upload a picture, change a picture etc...
Another example would be a notification screen where you can navigate to view and mark as read etc...notifications you have received.
I can write the code to test this by for example by creating a ton of methods in that 1 class and then calling these from the main testrunner class. There has to be a better organized way where I can have a separate class for functionality but wont I then have to create a new object for each test?
Sorry about the confused post I'm trying to learn Java thoroughly and selenium also.
EDITED
I have copied the process of creating a page object hybrid model that is documented in the YouTube video:
https://www.youtube.com/watch?v=gxwh8D_tx-0
I created a Pages package which contains all of the Page specific class such such ProfilePage, NotificationPage etc...
I have a second package which contains the tests and a testbase class which generates the driver object, opens the browser.
I want to get to the stage where in my tests class I can have a specific class for a test for example:
class test_that_user_can_upload_profile_picture
When I create such a class I have methods inside the class such as: test_that_navigation_to _profile_page_successful()
test_to_upload_valid_picture()
Should such navigation methods be inside this class?
Also I find that in order to access my methods from a package I need to mark my methods as static. Is this ok? I noticed on the youtube video the instructors methods were not static. Looking at the setup I dont quite understand why I cant access the methods unless I mark them as static. The error i get is
"Cannot make a static reference to a non-static method"
Here is my setup:
Also Im finding that in my ProfilePageNavigation class I have a bunch of methods that run in a specific order based alphabetical order.
Is it simply the case I should just have 1 method in each test class and just call the page classes methods(or any other pertinent class) to execute this test? If it is just 1 method inside each test class then wouldnt I have too many test classes each with a name like (for example) upload_valid_profile_picture with a method using the same name? and then another class with upload_invalid_profile_picture with it's method. I dont want to go down that path - how do I resolve that?
Also all my Pages class methods have to take WebDriver driver as a parameter is there any way around this - it is a lot of duplication.
If you could point me on the right track and let me know in it is ok to have the pages class methods as static it would be appreciated.
I guess I just want to know whether I am on the right track or going down the wrong route at this early stage.
#tarquin - you can find many articles on that #web, There are multiple ways to handle your code and work with it, my way is :
Create a objects repository in notepad or excel, from where you can pick/change/manage all your objects.
Create a class with all re-usable methods.
Create a class of your tests.
Thanks
Keshav
Ok, I have multiple classes in my testNG suite and all the methods inside those classes has the priority defined. When I run the single class, all the methods runs in a order defined as per the priority but when I run multiple classes, testNG doesn't run it in sequential order. First, it'll run single method from Class A then it'll run another method from Class B and then another method from Class C.
I want testNG to run all the methods from Class A and then move to other classes and run all the methods from those classes before moving to other class. Is there any way to achieve this ?
This post should cover how to retain the order specified for classes while you use priority.
I am involved in multiple projects in my company for manual testing. When we have so many test cases in the project we have to automate regression suite for those. Now problem is I have to have a portable framework that work for any project I move to. I simply import my java project(as existing maven project) and start executing selenium test cases after writing them. As of now, this is how I am doing but I don't know if this the optimum way or not.
I create a maven project, which gives, few source folders ready to use./myproject/src/main/java and /myproject/src/test/java.
In /myproject/src/test/java folder I create a class which has setup() and teardown() methods.
I create another class by the name "Define" where I define variables/string/class objects example:this class has WebDriver driver; or UserLogin userlogin = new UserLogin();
I create more classes in /myproject/src/test/java by the name of functionality let say "CreateZoo" and extend them with Define class. Later I use methods of these classes in classes inside /myproject/src/main/java, for example: A class of Main package would be "DailyTests" and I call methods here from classes inside /myproject/src/test/java
Apart from this I keep chromedriverexe, properties file, data.xls in main>>resources folder.
I also have CommonFunctions class extends Define in /myproject/src/test/java, here I have written common java functions that I use frequently like :
class CommonFunctions extends Define {
/*
*
* Click linktext, click partial, name,id,xpath,css, classname
*/
static class clik {
static void txt(String locator) {
new WebDriverWait(driver, 60).until(
ExpectedConditions.presenceOfElementLocated(By
.linkText(locator))).click();
}
and another common fucntions class for myproject like: I have written a long method for user login and I call it where ever I need it.
So, the way I am doing above is good or should I have classes by the name of each page, for example "LoginPage.java"
This class would've html elements defined using pagefactory(as of now I am not using page factory.)
I am a selenium2.0 aspirant , I don't have much experience on it. How to beautify code and create/maintain selenium projects?
Your code structure is fairly optimal.
But I do have some suggestions:-
In my opinion, maintainability of test code can be improved we you define classes based on pages instead of functionality.
Consider a scenario where you have to click on manage account>edit>change address. There can be a similar scenario where you have to click on manage account>edit>change username. In both the scenarios the first 2 steps are same. But they have to be written twice one in ChangeAddress Class and other in ChangeUserNameClass. If property of edit changes, we have to change the code in places. So less maintainability and redundant code.
This can be avoided by defining classes according to functionality. Class1 contains clickManageAccount(), Class2 contains clickEdit() and Class3 contains clickChangeAddress() and changeUserName().
So it is just a matter of assembling the methods above methods in a Junit class based on the functionality.
This will ensure each Test is modular and maintainable. Also page factory can be efficiently used in each class.
Please consider the following folder structure :-
/myproject/src/test/java/page - Contains all your page classes which extends define class
/myproject/src/test/java/common - Contains all common classes and define class
/myproject/src/test/java/scenarios - Contains JUnit test class with #Before[setUp()], #After[tearDown()] and #Test methods. #Test Methods use methods in page classes to assemble the required methods for a particular scenario.
/myproject/src/main/resources - Contains resources like chromedriverexe, properties file, data.xls
/myproject/src/main/java/ - Contains classes like DailyTests which use classes in /myproject/src/test/java/scenarios
This is just my thoughts. Please do revert back with your ideas on it.
I'd look at implementing cucumber (with Selenium): http://cukes.info/
It'll make your code OO, cleaner, and easier to maintain and read.
I've written a number of tests, divided not only into separate classes but, depending on what area of my application they're testing, into separate sub-packages. So, my package structure looks a bit like this:
my.package.tests
my.package.tests.four
my.package.tests.one
my.package.tests.three
my.package.tests.two
In the my.package.tests package I have a parent class that all tests in the sub-packages one through four extend. Now, I would like to choose the order in which the tests are run; not within the classes (which seems to be possible with the FixMethodOrder annotation) but the order of the classes or sub-packages themselves (So those in sub-package one first, then those in two, ect.). Some of the test classes use the Parameterized runner, just in case that makes a difference. Choosing the order is not required for the tests to succeed, they are independent of each other; it would however be helpful to sort them to reflect the order in which the various parts of the program are normally used as it makes the analysis a bit easier.
Now, ideally I would like to have some configuration file which tells JUnit which order the tests should be executed in; I'm guessing however that it won't be so easy. Which options do I have here and what would be the easiest one? I'd also prefer to only have to list the sub-packages, not the various classes in the packages or even the test functions in the classes.
I'm using Java 1.6.0_26 (I don't have a choice here) and JUnit 4.11.
You can do this with test suites. (you can "nest" these, too)
#SuiteClasses({SuiteOne.class, SuiteTwo.class})
#RunWith(Suite.class)
public class TopLevelSuite {}
#SuiteClasses({Test1.class, Test2.class})
#RunWith(Suite.class)
public class SuiteOne {}
#SuiteClasses({Test4.class, Test3.class})
#RunWith(Suite.class)
public class SuiteTwo {}
... And so on. Use the "toplevelsuite" as an entry point, and the tests will execute in the order in which you define the #SuiteClasses array.
As for the methods within a class, you can specify the order they execute in with #FixMethodOrder (as you have already mentioned in your question.
Is there a feasible way to get my own code run whenever any class is loaded in Java, without forcing the user explicitly and manually loading all classes with a custom classloader?
Without going too much into the details, whenever a class implementing a certain interface read its annotation that links it with another class, and give the pair to a third class.
Edit: Heck, I'll go to details: I'm doing an event handling library. What I'm doing is having the client code do their own Listener / Event pairs, which need to be registered with my library as a pair. (hm, that wasn't that long after all).
Further Edit: Currently the client code needs to register the pair of classes/interfaces manually, which works pretty well. My intent is to automate this away, and I thought that linking the two classes with annotations would help. Next, I want to get rid of the client code needing to keeping the list of registrations up to date always.
PS: The static block won't do, since my interface is bundled into a library, and the client code will create further interfaces. Thus, abstract classes won't do either, since it must be an interface.
If you want to base the behavior on an interface, you could use a static initializer in that interface.
public interface Foo{
static{
// do initializing here
}
}
I'm not saying it's good practice, but it will definitely initialize the first time one of the implementing classes is loaded.
Update: static blocks in interfaces are illegal. Use abstract classes instead!
Reference:
Initializers (Sun Java Tutorial)
But if I understand you right, you want the initialization to happen once per implementing class. That will be tricky. You definitely can't do that with an interface based solution. You could do it with an abstract base class that has a dynamic initializer (or constructor), that checks whether the requested mapping already exists and adds it if it doesn't, but doing such things in constructors is quite a hack.
I'd say you cleanest options are either to generate Code at build time (through annotation processing with apt or through bytecode analysis with a tool like asm) or to use an agent at class load time to dynamically create the mapping.
Ah, more input. Very good. So clients use your library and provide mappings based on annotations. Then I'd say your library should provide an initializer method, where client code can register classes. Something like this:
YourLibrary.getInstance().registerMappedClasses(
CustomClass1.class,
CustomClass2.class,
CustomClass3.class,
CustomClass4.class
)
Or, even better, a package scanning mechanism (example code to implement this can be found at this question):
YourLibrary.getInstance().registerMappedClassesFromPackages(
"com.mycompany.myclientcode.abc",
"com.mycompany.myclientcode.def"
)
Anyway, there is basically no way to avoid having your clients do that kind of work, because you can't control their build process nor their classloader for them (but you could of course provide guides for classloader or build configuration).
If you want some piece of code to be run on any class loading, you should:
overwrite the ClassLoader, adding your own custom code at the loadClass methods (don't forget forwarding to the parent ClassLoader after or before your custom code).
Define this custom ClassLoader as the default for your system (here you got how to do it: How to set my custom class loader to be the default?).
Run and check it.
Depending on what kind of environment you are, there are chances that not all the classes be loaded trouugh your custom ClassLoader (some utility packages use their own CL, some Java EE containers handle some spacific areas with specific classLoaders, etc.), but it's a kind of aproximation to what you are asking.