How to organize webdriver project in eclipse? - eclipse

I've started a few WebDriver projects in Eclipse Juno but i'm not satisfied with my structure, i think is to stupid and not efficient at all.
Beneath you can see my project three now. The TEST_xxx.java files are functions to trigger the files in the test package.
Here is an example of one function in a TEST_xxx.java file:
public void a_search_product_by_sku(String sku) throws InterruptedException {
System.out.println("Running Testsuite 3 - Navigation - Testcase 1 - Search product by SKU");
tests.navigation nav = new tests.navigation(BASE_URL, driver);
nav.search_product_by_sku(sku);
}
This calls the function search_product_by_sku() that is inside the navigation class inside the test package. This function look like this:
public void search_product_by_sku(String sku) throws InterruptedException {
driver.get(url + "/k/k.aspx");
driver.findElement(By.id("q")).clear();
driver.findElement(By.id("q")).sendKeys(sku);
driver.findElement(By.cssSelector("input.submit")).click();
boolean status = driver.findElement(By.cssSelector("BODY")).getText().matches("^[\\s\\S]*Status:[\\s\\S]*$");
Assert.assertEquals(true, status);
}
All this seems too hard to maintain, and since I'm not a very experienced programmer I'm really out of ideas and i hoped that someone here could help me.
Thanks in advance!

First a class name should start with a capital letter.
date should be Date.
Instead of having four classes in tests package. You can merge the 4 classes into a single class.
And the classes, and the testing classes would be good if they are in the same package.

Related

Can anyone help me how to write junit for this code

public class Main {
public static void main(String[] args) throws IOException, URISyntaxException, TransformerException {
TransformerFactory factory = TransformerFactory.newInstance();
Source xslt = new StreamSource(new File("transform.xslt"));
Transformer transformer = factory.newTransformer(xslt);
Source text = new StreamSource(new File("input.xml"));
transformer.transform(text, new StreamResult(new File("output.xml")));
}
}
The first step in writing JUnit tests is knowing what you want to test. So that is the best place to start. First, look at your code and try to break down which are the moving pieces. Ask yourself "what could possibly break? what am I worried about not working?" For instance, you could test what happens if transform.xslt doesn't exist.
I think step one for you is to take all of the code you currently have in main() and move it into an object. You can start by making it an instance method on the class. That will give you a way to decouple the code you want to test from running main.
If you search online you will find many tutorials on JUnit, it will likely help you to work through a few of them.

Run As TestNG is not shown for class extending AbstractTestNGCucumberTests

Please note that I've searched for this particular question & found couple of them but none of them had scenario related to cucumber integration.
I've a test runner class extending AbstractTestNGCucumberTests.
I've also installed Eclipse TestNG plugin as well 6.12
Also adding entry under TestNG under Run Configuration, didn't help to solve the issue.
Mac + Eclipse 4.7.0
#CucumberOptions(features={"src/test/resources/WunderlistAndroid.feature"}, strict = false, format = { "pretty","json:target/cucumber.json" }, tags = { "~#ignore" })
public class WLSignIn extends AbstractTestNGCucumberTests{
#BeforeClass
public void launchAppiumServer(){
//code doing desired action
}
#AfterClass
public void killAppiumServer(){
//code doing desired action
}
}
The problem is due to the fact that the eclipse TestNG plugin doesn't see any #Test methods in your class. I believe the plugin is contextual in nature and hence shows the Run As > TestNG Test only when it sees atleast one #Test method in your test class. Since the #Test method resides in your base class, the plugin doesnt see that and hence you don't see it.
To get past this, you can perhaps add a dummy test method such as the one below and that should bring back the Run as > TestNG test option.
#Test(enabled=false)
public void dummyTestMethod() {}
On a side note: You might want to file this as an issue in the TestNG project and see if its worth getting fixed.
Details that can be used for the bug :
If the base class resides within a jar (and has one or more #Test annotated test methods) then the eclipse testng plugin doesn't see the child class (WLSignIn) the first time. But after one adds a disabled #Test method to the child class (WLSignIn) the option shows up. This happens irrespective of whether the child class extends from another class in the same project or from another class which resides in a jar (in your case cucumber.api.testng.AbstractTestNGCucumberTests)

How to verify a statc methode in Moq

I am new to Nunit and Moq
I have a static class like this:
public static class StaticClass1
{
public static void Prepare()
{
//some logic
}
}
public static class StaticClass2
{
public static void Initialize(some_parameter)
{
//some logic
if (some_condition(some_parameter))
{
StaticClass1.Prepare();
}
}
}
I need to test the function AccountService.Initialize() in which I need to verify StaticClass1.Prepare() is being called at least once
I think that to answer this question I would say something like "You need to get experience in how to layer a project".
When unit testing a method you want to unit test that single method, and mock the dependencies, exactly as you try to do if I understand you correctly. Now it's not optimal to call static public methods from one class to another static method in another class since it makes it difficult to isolate you unit tests and what they should test (you end up with testing two completely different methods in the same unit test instead of separating the code and unit tests).
On another approach you break the D in SOLID (Dependency inversion principle) that you can read more about here -> https://en.wikipedia.org/wiki/SOLID_(object-oriented_design). You want to depend upon abstractions rather than concrete classes.
Lastly I thought that I would be a bit selfish and share a link to an article series that I have written myself. It's about Test Driven Development and uses Moq as unit testing tool and focuses on how to think when layering and unit testing a complete project (in a small scale). I'm absolute certain that it will help you understand on how to continue with you own projects and code.
It's based upon 4 articles. The first in the series is here -> http://www.andreasjohansson.eu/technical-blog/getting-started-unit-testing-a-web-project-part-1-introduction-and-setting-up-the-project/
Hope it helps!

Eclipse EclEmma missed instructions

I'm using Eclipse-STS + EclEmma plugin to see coverage of my code. In all my abstract util classes (with only static methods) I see 3 missed instructions (Instructions Counter report) at the class definition line:
No marker available at the left of the red line, so I do not know exactly what are these instructions. Maybe some constructors? What can I do to cover them?
One way I found to achieve 100% covering is to write a test method like this:
#Test
public void coverage(){
KeyEscaper a = new KeyEscaper() {
};
}
As soon as the issue touches only utils classes with all static methods, it's not a problem to instantiate them anonimously in such way.

Is there a equivalent of testNG's #BeforeSuite in JUnit 4?

I'm new to the test automation scene so forgive me if this is a stupid question but google has failed me this time. Or at least anything I've read has just confused me further.
I'm using JUnit 4 and Selenium Webdriver within Eclipse. I have several tests that I need to run as a suite and also individually. At the moment these tests run fine when run on their own. At the start of the test an input box is presented to the tester/user asking first what server they wish to test on (this is a string variable which becomes part of a URL) and what browser they wish to test against. At the moment when running the tests in a suite the user is asked this at the beginning of each test, because obviously this is coded into each of their #Before methods.
How do I take in these values once, and pass them to each of the test methods?
So if server = "server1" and browser = "firefox" then firefox is the browser I want selenium to use and the URL I want it to open is http://server1.blah.com/ for all of the following test methods. The reason I've been using seperate #Before methods is because the required URL is slightly different for each test method. i.e each method tests a different page, such as server1.blah.com/something and server1.blah.com/somethingElse
The tests run fine, I just don't want to keep inputting the values because the number of test methods will eventually be quiet large.
I could also convert my tests to testNG if there is an easier way of doing this in testNG. I thought the #BeforeSuite annotation might work but now I'm not sure.
Any suggestions and criticism (the constructive kind) are much appreciated
You can adapt the solution for setting a global variable for a suite in this answer to JUnit 4 Test invocation.
Basically, you extend Suite to create MySuite. This creates a static variable/method which is accessible from your tests. Then, in your tests, you check the value of this variable. If it's set, you use the value. If not, then you get it. This allows you to run a single test and a suite of tests, but you'll only ask the user once.
So, your suite will look like:
public class MySuite extends Suite {
public static String url;
/**
* Called reflectively on classes annotated with <code>#RunWith(Suite.class)</code>
*
* #param klass the root class
* #param builder builds runners for classes in the suite
* #throws InitializationError
*/
public MySuite(Class<?> klass, RunnerBuilder builder) throws InitializationError {
this(builder, klass, getAnnotatedClasses(klass));
// put your global setup here
MySuite.url = getUrlFromUser();
}
}
This would be used in your Suite like so:
#RunWith(MySuite.class)
#SuiteClasses({FooTest.class, BarTest.class, BazTest.class});
Then, in your test classes, you can either do something in the #Before/#After, or better look at TestRule, or if you want Before and After behaviour, look at ExternalResource. ExternalResource looks like this:
public static class FooTest {
private String url;
#Rule
public ExternalResource resource= new ExternalResource() {
#Override
protected void before() throws Throwable {
url = (MySuite.url != null) ? MySuite.url : getUrlFromUser();
};
#Override
protected void after() {
// if necessary
};
};
#Test
public void testFoo() {
// something which uses resource.url
}
}
You can of course externalize the ExternalResource class, and use it from multiple Test Cases.
I think the main functionality of TestNG that will be useful here is not just #BeforeSuite but #DataProviders, which make it trivial to run the same test with a different set of values (and won't require you to use statics, which always become a liability down the road).
You might also be interested in TestNG's scripting support, which makes it trivial to ask the user for some input before the tests start, here is an example of what you can do with BeanShell.
It might make sense to group tests so that the test suite will have the same #Before method code, so you have a test suite for each separate.
Another option might be to use the same base url for each test but navigate to the specific page by getting selenium to click through to where you want to carry out the test.
If using #RunWith(Suite.class), you can add static methods with #BeforeClass (and #AfterClass), which will run before (and after) the entire Suite you define. See this question.
This of course won't help if you are referring to the entire set of classes found dynamically, and are not using Suite runner.