I am currently writing Selenium WebDriver tests for a variety of websites each using the same proprietary framework.
Because of this, there are many test cases that can be quite similar across different websites. As such I have made my test classes as generic as possible and made it so that every XPath/CSS Selector/ID used to locate elements is defined in a Constants class, which is unique to every project.
But, in some cases, the code for the same test can be the same across different websites, since I wrote them generically.
In addition each test is a direct/indirect extension of a BasicTest class which contains code that is likely to be reused by different tests (ex: WebDriver instance declaration, etc)
The way I thought about setting my test structure was the following:
one generic project that is "reused" by each subsequent project;
one project per website with its own definition of the Constantsclass and a TestSuite class that it can use to run both generic tests and tests specific to itself.
This would allow me not to have copies of these generic tests in each of my test projects.
The problem is that I don't really know how to set this up. The GenericProject is going to contain tests that require variables from Constant, but it makes no sense to have generic Constants. Plus, will I be able to call those tests inside my website project-specific TestSuites? If I redefine Constants in each specific project, will those constants be used for the generic tests defined in GenericProject?
How can I even set it up so that I can reuse Project A's classes inside of Project B, C, D... etc?
Extract your constants to a properties file which exists in each module as src/test/resources/common.properties.
Use org.apache.commons:commons-configuration2 PropertiesConfiguration to read this file. It will handle nested properties just fine.
Common code can be shared by depending on your GenericModule. Official instructions for two models of doing this (extract common tests to a new module or use a test-jar) are here
In general in order to reuse code over projects you would create a library containing the reusable code. In order to do so you'd need to think about a suitable API for the library.
This contains decisions about:
How will functionality be called from dependent code
How will dependent code provide required data.
If you are using constants for e.g. CSS selectors, that are different but have the same semantics, e.g.
root frame
side panel
main area
...
you might want to define an interface that the dependent code can provide. This could look like:
interface CssSelectors {
String rootFrame();
String sidePanel();
//...
}
If you are building this for tests you might also want to use features of your test framework (e.g. Rules in JUnit).
When reusing code in tests you also should consider another aspect:
If s.o. reads the tests written with your library, will she be able to sufficiently understand what is happening behind the border of the library to understand what the test is all about? This is a lot more of a question when dealing with test code than with production code as for test coverage and validity of tests it often matters a lot more how a setup or verification is done than is the case for production code.
Related
I'm currently working at my job to perform GUI testing of our web page using Selenium 2 via Java in Eclipse. I've been trying to program my tests in such a way that I maximize the amount of code I can reuse and as a consequence I now have a lot of helper methods that function almost like a framework. This has lead to my test class becoming fairly bloated with only one method used as the actual test and the rest being the implementation of the test.
Currently I just run the testing right from Eclipse with all my methods being static.
From what I understand there are a couple different ways I could try to separate things out:
One way would be to put all the methods into a class I use as a framework and extend it when writing an actual test, but I don't know if having a framework in a framework (Selenium) makes sense.
Another way would possibly be making my helper methods into an object where I can have one of these objects for each test. I don't know if this is good practice though, or if it will cause problems down the road. It would also mean I'd have to type more to do the same amount of testing.
My main questions are:
What's the best way to split up my testing class into test classes and an implementation class?
Is what I'm doing outside the intended usage of Selenium?
The best practice is that create a page object model for each web UI.That will help you to access the web element easily.selenium provide that feature and you also have to do some R&D things.
Home_Page.lnk_MyAccount(driver).click();
LogIn_Page.txtbx_UserName(driver).sendKeys("testuser_1");
LogIn_Page.txtbx_Password(driver).sendKeys("Test#123");
And put all selenium related actions into a one class.like Action.click(),Action.search(), or what ever your common set of actions.
Next thing is that reusable code implement via a function.let say login(usernName,Password) then handle the login code inside that.and you can reuse thease codes in your other places.always try to modularize your implementation.
I am new to Cucumber and I am using cucumber-java. The cucumber feature files look great. However, the reuse of step definitions really gets in the way about organizing the step definition code. The most intuitive way for me to organize the step definitions is just to follow the organization of the feature files, namely, one class for one feature. However, this way is screwed if there are two identical steps in two feature files, because you will miss one step in one of the classes, which breaks the coherence of the entire structure. However, I cannot convince myself to use other ways right now. So, what is a sensible way to organize step definitions when using cucumber-java?
Thank you very much.
Start with the way you are already doing and once you recognize that a step is reused, move it a class ReUsableSteps or something. This way, if a step does not exist in its class then it should be in ReUsableSteps. Just a thought.
You can have a separate package as placeholder for classes that defines common steps. Add that package as glue.
The best way to use cucumber is to minimize the duplication of step definition. What we should focus on while writing step definition is to avoid any code specific to a class or functionality in steps method of StepDefinition class because that way it can not be generalized, it should have common code which can be used for different steps and code for propagating to separate class for which step is meant and specific logic for each step should reside in separate class. This way we can avoid duplication.
Example:-
Suppose we have component feature file which contains step "Component A has to receive responses", its implementation class is ComponentStepDefinition class, when we implement this in step definition we should not use any logic for iterating or calculating responses for component A there, rather pass the value to a class which performs A related task, in this way to you have to implement "Component B has to receive responses" then same step definition can be used and B's logic will be in another class.
Sort your step definitions by common functionality as related to your domain. They do not have to be linked to specific feature files.
For example, one of our features is to provide our partners with scores (how are they doing on our platform). We have several step definitions related to those scores in a ScoreSteps file. We might have other steps related to partners, those would be in a PartnerSteps file. This also makes it easier to use helper methods related to a certain domain object.
These files would be completely different for you, depending on your domain.
Also note that your IDE will know if a step has already been defined or not (at least, in IntelliJ steps that are undefined are marked in yellow).
Reusing steps is critical for maintenance reasons. That doesn't mean trying to shoehorn steps here and there, but finding a balance between reusability and understanding. As already said above, arranging them into a Common or Reusable package is a pretty good idea. This is something to be done as you go, because you don't always know whether a step is going to be reused or not. In this sense, frequent refactoring of step definitions will be quite normal. Actually it is an indicator of code aliveness, so don't hesitate to make any changes to get the test scenarios clear enough and the testing code as clean as possible. It is just the same well-known coding principles, applied to testing.
One thing that helped me with this task was a utility class (actually it was a set of classes) that allowed me to know which steps and steps definitions exist, the class in which the step definition is defined, the feature files and test scenarios that make use of them, etc. You can even implement advanced options such as searching for steps or steps definitions that contain such and such keywords, or getting to know the step definitions that are not used any longer, etc. Kind of a dictionary.
It can be achieved by either processing the java classes that belong into the 'glue' folder and gather all the regular expressions associated to the gherkin annotations, or by parsing the feature files with the help of a Gherkin parser. Although you may want to have both approaches implemented, as they are not mutually-exclusive; on the contrary, they complement each other.
This is something you may not need when having just a few test scenarios. But as this number grows bigger and bigger, you will find such a mechanism really valuable.
This can be done easily by using multiple test runner classes for multiple feature files.
You can create same steps for different features as long as you are specifying the glue code in your test runner. Glue will make sure the cucumber checks only in the path specified for the steps during execution.
Then you can maintain a suite xml configuration like TestNG.xml for running which all features I want.
#RunWith(Cucumber.class)
#CucumberOptions(monochrome = true, features = "src/test/java/com/abc/batch/xyz/payout/bbq/monthly",
plugin = { "pretty", "html:target/cucumber-html-reports" }, strict = true, glue = {"com.abc.batch.xyz.payout.bbq.monthly" })
#Rollback(false)
The way I organize my cucumber tests are like I have a java package for a cucumber feature where I will have the steps definitions class, feature file, test data files for those tests and Hooks class.
The advantage is that when I try to look for the step definitions in the step class, I know where exactly to look at and the chances of getting a step definition conflict is zero unless you have added the same definition in that package twice.
We are considering to use Cucumber on our project for acceptance testing.
When we write a scenario in a Cucumber feature, we write a list of Given, When and Then statements.
As we use cucumber-jvm project, the Given, When and Then statement are related to Java methods in (JUnit) classes.
I want to know what is the best organization for the code related to Given / When / Then in the project structure. My main concern is the maintenance of the cucumber tests on a big project, where the number of scenario is quite important, and especially regarding the items that are shared between features.
I can see at least 2 main approaches:
Each feature is related to it's own JUnit class. So if I have a foo/bar/baz.feature cucumber file, I will find the releated foo.bar.Baz JUnit class with the adequate #Given, #When and #Then annotated methods.
Separate #Given, #When and #Then methods into "thematic" classes and packages. For example, if in my cucumber scenario I have a statement Given user "foo" is logged, then the #Given("^user \"([^\"]*)\" is logged$") annotated method will be located in the foo.user.User class method, but potentially, the #When method used later in the same cucumber scenario will be in a different Java class and package (let say foo.car.RentCar).
For me, the first approach seems good in the way that I can easily do the relation between my cucumber features and my Java code. But the drawback is that I can have a lot of redundancies or code duplication. Also, it may be hard to find a possible existing #Given method, to avoid to recreate it (the IDE can help, but here we are using Eclipse, and it does not seem to give a list of existing Given statement?).
The other approach seems better essentially when you have Given conditions shared among several cucumber feature, and thus I want to avoid code duplication. The drawback here is that it can be hard to make the link between the #Given Java method and the Given cucumber statement (maybe, again, the IDE can help?).
I'm quite new to cucumber, so maybe that my question is not a good question, and with time and experience, the structure will be self-evident, but I want to get good feedbacks on its usage...
Thanks.
I would suggest grouping your code according to the objects it refers to, similar to option #2 you presented in your question. The reasons being:
Structuring your code based on how and where it's being used is a big no-no. It's actually creating coupling between your feature files and your code.
Imagine such a thing in your product's code- the SendEmail() function wouldn't be in a class called NewEmailScreenCommands, would it? It would be in EmailActions or some such.
So the same applies here; structure your code according to what it does, and not who uses it.
The first approach would make it difficult to re-organize your feature files; You'd have to change your code files whenever you change your feature files.
Keeping code grouped by theme makes DRYing it much easier; you know exactly where all the code dealing with the user entity is, so it's easier for you to reuse it.
On our project we use that approach (i.e BlogPostStepDefinitions class), with further separating the code, if the class gets too large, to types of steps (i.e BlogPostGivenStepDefinitions).
We have also started using Cucumber-JVM for acceptance testing and have similar problems with organising code. We have opted to have 1 step definition class for each feature. At the moment this is fine as the features we are testing aren't very complex and quite separate, there is very little overlap in our features.
The second approach you mentioned would be better I think, but it is often challenging to tie together several different step definition classes for a single scenario. I think the best project structure will become clearer once you start adding more features and refactor as normal.
In the meantime here is an Eclipse plugin for cucumber,
https://github.com/matthewpietal/Eclipse-Plugin-for-Cucumber
it has syntax highlighting as well as a list of existing available steps when writing a feature.
On the current project I am taking part in, we asked ourselves the very same question.
After fiddling a bit with the possibilities, what we opted for was a mix of both the solutions you exposed.
Have steps regrouped in theme-centric common steps classes
app-start steps
security check steps
[place random feature concern here] steps
And classes of scenario (and in some case even feature) specific steps
This was to have at the same time the grouping of factorized code which is pretty easily identifiable on it's whatabouts, whereabouts and whatnot.
Yet it allows not to clutter those common classes with overly specific code.
The wiring between all these classes is handled by spring (with cucumber spring which does a great job once you get the hang of it).
I've got 2 questions about organising Unit tests.
Do I have to put test to the same package as tested class, or can I organise tests in different packages?
For example if I have validity and other tests, is it correct to split them into different packages, even if they are for same class?
What about mock and stub classes? Shall I separate them from packages containing only tests, or put them together?
The way we do our JUnit test cases is to put them in the same package, but in a different root directory. Since we use Maven, we just use the standard locations making the structure similar to the following.
src/main/java/com/foo/Bar.java
src/test/java/com/foo/BarTest.java
Obviously there's more to the structure, but this lets us build the tests separately from the mainline code, but still access protected classes and the like. With respect to different types of tests, this is very subjective. When we started our testing effort (which unfortunately started after development), I tried to keep things pretty isolated. Unfortunately, it quickly became a nightmare when we got to the 500+ test case point. I've since tried to do more consolidation. This led to reduced amounts of code to maintain. As I said, though, it's very subjective.
As far as test-only code, we keep it in a separate com.foo.test package that resides only in the src/test/java tree.
I too tend to put my tests in the same package but under a different root directory. This allows me to test package-private classes or access packing-private classes while testing something else in the package. They are kept in a separate directory tree to allow excluding them from the deployed result (in particular to ensure that test code didn't accidentally get into production code). What matters most, however, is what works for your situation.
In terms of how many test classes per production class, the theory I've seen is that you write one test class per fixture, that is per setup structure. In many cases that is the same (or close enough) to one test class per production class, but I have sometimes written more test classes (in particular equality tests tend to be separated) for a give production class, and occasionally one test class of for a group of (related) production classes (say, for testing the Strategy pattern).
Mostly, I don't worry too much about the theory, but rework the tests as needed to keep duplication to an absolute minimum.
Keeping it the same package allows you to use package-private visibility for code that is intended to be accessed via the test only.
Regarding using separate root directories, that is a good practice. It also has an advantage for us, since we use IDEA, IDEA recognizes that production code cannot reference test code.
In terms of keeping them separate, there is a great power in having one, and only one, test class per production class at the unit level. Of course, some classes get created in production as part of refactoring that have no test classes at all, and that is fine, but when you want to know what test tests a certain class, having a convention that says ClassNameTest is the tests for ClassName is very helpful.
TestNG is much friendlier to this paradigm than JUnit, though.
Test classes should be rather in different packages, it's easier to separate them from the production code when you package it for release. I usually keep lots of test fluff in those packages, all sorts of mocks, configurations, scenarios.. But when you build - it doesn't get it. In some situations, it's a good idea to keep your testing stuff even in different projects. Depends.
I'm new to unit testing using nunit (and Java development in general). When creating unit tests for private methods on classes, it looks as though the test file must be in the same package as the class being tested. What is the typical way of avoiding exporting the APIs of the unit tests? Can I make the classes/test methods package-protected? Or do developers typically have a separate build for release that excludes unit test files?
I can tell IntelliJ or Ant not to package JUnit tests in the deployment. I have tests in a separate directory from the source code, which is what makes it possible.
Don't mingle source and test classes together. Keep them separate to make it easier for the tool/script you use to deploy.
The test file does not necessarily have to be in the same package as the class being tested. In fact, it is a good practice to have the test files in a completely separate package, allowing them to test the public API without being concerned with package-level implementation details.
Alternately, you can set up your build script (e.g. Nant) to ignore files containing "Test" when you build your release executable.
Personally my approach is only to test exposed functionality, so you end up testing well encapsulated parts only.
This usually leads my design to contain small classes with well defined functionality, which are easier to test.
Generally, when unit testing you shouldn't be concerned with the internals of what you're testing, so I find this is the best way to approach it.
I also agree it's best to seperate test and production code.
Keep test source code out of application source code. In general, only test exposed functionality. If you really need to test private behavior, create a test object that extends the real object and allows publec access to the private behavior.
I think it's a mistake to move your test code out of the package of the CUT (Class Under Test). At some point you may want to test a protected method or class, and having your test code in another package makes that hard or impossible.
A better solution is to create a separate directory for your test code that simply mirrors the package structure of your production code. Here's what I do:
src/main/java/com/example/Foo.java
src/test/java/com/example/FooTest.java
Then your build script can very simply ignore src/test/** when it comes time for packaging and deployment.