Eclipse: how to update a JUnit test file with newly added method in the source file? - eclipse

Using Eclipse (Helios), I could create a JUnit test file ClassATest.java of the source file ClassA.java by using New -> JUnit Test Case -> Class under test..., then choose all the methods of ClassA to be tested.
If later we add some more methods to ClassA, how do we easily reflect this addition in ClassATest ? (No copy/paste plz).

One solution is to use MoreUnit
With MoreUnit installed to Eclipse, one can right click onto the newly added method (and not yet unit tested), and choose "Generate Test"
Of course, if one always follows the writing-test-before-writing-method style, then this solution is not needed. However in reality sometimes you don't have a clear idea of what you would want to do, in that case you would have to code up some method, play with it, then rethink and code again until you are satisfied with the code and want to make it stable by adding unit test.

You should look into creating a JUnit test suite which will execute all tests within the classes you specify. Thus, adding new test cases is as simple as creating a new class and adding it to the #Suite.SuiteClasses list (as seen below).
Here's an example.
Example JUnit Test Suite Class:
#RunWith(Suite.class)
#Suite.SuiteClasses({
TestClassFoo.class
})
public class ExampleTestSuite {}
Example Test Case class:
public class TestClassFoo {
#Test
public void testFirstTestCase() {
// code up test case
}
}

Related

Migration problems when migrate from NUnit 2.X to NUnit 3.X

I'm using NUnit 2.X library but want to use NUnit 3.X now. I have some problems about migration from 2.X to 3.X. First i have a setup fixture class. Here is the 2.X version;
using System;
using System.IO;
using System.Reflection;
using HalisEnerji.QuantSignal.Logging;
using NUnit.Framework;
namespace HalisEnerji.QuantSignal.Tests
{
[SetUpFixture]
public class Initialize
{
[SetUp]
public void SetLogHandler()
{
Log.LogHandler = new ConsoleLogHandler();
}
}
}
First problem is fixed via change "Setup" attribute with "OneTimeSetUp" attribute. Second problem fixed via add some codes for set test directory. Because i'm using Re-Sharper test engine. Here is final shape of setup fixture;
using System;
using System.IO;
using System.Reflection;
using HalisEnerji.QuantSignal.Logging;
using NUnit.Framework;
namespace HalisEnerji.QuantSignal.Tests
{
[SetUpFixture]
public class Initialize
{
[OneTimeSetUp]
public void SetLogHandler()
{
Log.LogHandler = new ConsoleLogHandler();
var assembly = Assembly.GetExecutingAssembly();
var localPath = new Uri(assembly.CodeBase).LocalPath;
var direcotyName = Path.GetDirectoryName(localPath);
if (direcotyName != null)
{
Environment.CurrentDirectory = direcotyName;
}
}
}
}
Well after solve setup fixture problem, my real problems begins with use TestCaseSource/TestCaseData. Here is sample 2.X version;
[Theory]
[TestCaseSource("CreateSymbolTestCaseData")]
public void CreateSymbol(string ticker, Symbol expected)
{
Assert.AreEqual(Symbol.Create(ticker), expected);
}
private TestCaseData[] CreateSymbolTestCaseData()
{
return new []
{
new TestCaseData("SPY", new Symbol(Security.GenerateEquity("SPY"), "SPY")),
new TestCaseData("EURUSD", new Symbol(Security.GenerateForex("EURUSD"), "EURUSD"))
};
}
2.X version creating exception and my tests are fail. Shortly exception telling that TestCaseData provider method must be static. Well, after mark method with static identifier test working correctly but this time my other test failing (before use static identifier it's not failing). Why my other test failing? Because it's reading a file from test directory and somehow test working before setup up fixture codes run and change test directory!
Before use static identifier first SetUpFixture codes run and then tests code run. After use static identifier order changing my test that read file from test directory (which is Re-Sharper's temporary directory and not contain necessary file) run first after that SetUpFixture codes run. Any idea how all my tests to be successful?
UPDATE:
Explain some units;
I have Initialize.cs (part of my test assembly) which is responsible setup CurrentDirectory.
I have Config.cs (part of my project infrastructure assembly) which is my project configuration file and it has public static readonly Setttings property which is reading configuration file from CurrentDirectory.
I have ConfigTests.cs (part of my test assembly) which is contain some test methods for read/write Settings property.
When i debug tests;
Before use any static TestCaseSource, they are working below order;
A. Initialize.cs => Setup method
B. Config.cs => static Settings property getter method
C. ConfigTests.cs => first test method
So initialize working first others working later all tests successfully passing from test.
After use static TestCaseSource for inside other test file lets say OrdersTests.cs (excluded from project for first scenario after that included again), somehow working order is changing like below;
A. Config.cs => static Settings property getter method
B. OrdersTests.cs => static TestCaseSource method (not test method)
C. Initialize.cs => Setup method
D. ConfigTests.cs => first test method
E. OrdersTests.cs => first test method
So, my ConfigTests.cs tests failing because Initialize.cs working after Config.cs. I hope with this update my problem is more clear.
Is this problem related NUnit or Resharper or V.Studio? I don't know and all i know is my successfully passing tests are failing now!
UPDATE 2:
Chris,
Yes you are right. I explore project in detail and i saw the problem is related that my project's some classes accessing to static Config class and it's static Settings property (before run test setup fixture method and even before static test case source method!). You talk about order of process of test methods; NUnit doing tests like your said, not like i said. But when i try to use your solution (set current directory before test case source) it's not working. Because of that i solve my problem in another way. I'm not happy but at least my test methods working now. Could you please tell me what are the technical reasons that run static test case methods before initialize/setup method? Is this because of NUnit or because of infrastructure of .Net Framework? I'm not fanatic about NUnit and/or TDD. I don't have deep knowledge about these concepts but it does not make sense to me: run any method before setup method.
Thanks for your interest.
Because it's reading a file from test directory and somehow test working before setup up fixture codes run and change test directory!
How are you reading this file? You should use TestContext.CurrentContext.TestDirectory to get the test directory in NUnit 3, rather than relying on the location of the current directory. See the Breaking Changes page for details.
Edit: I also see you've tagged this ReSharper 7.1. You should be aware that this version of resharper does not support NUnit 3 - the first version that did is ReSharper 10. Your tests will appear to run correctly - however you may experience weird side effects, and this may break in any future version of NUnit.
Response to update:
Take a look at NUnit 3's Breaking Changes page. There are two relevant breaking changes between NUnit 2 and 3.
TestCaseSource's must now be static.
The CurrentDirectory is no longer set to Environment.CurrentDirectory by default.
The first you've solved easily enough. The second, is what's now causing you issues.
NUnit 3 runs it's methods in this order:
Evalute TestCaseSource methods (OrdersTests.cs)
Run SetUpFixture (Initialize.cs)
Run Test (ConfigTests/OrdersTests)
I'm not sure what Config.cs is being called before your TestCaseSource method - are you sure of that order? Does anything in CreateSymbolTestCaseData() call anything in Config.cs You could try rewriting your TestCaseSource as such:
private TestCaseData[] CreateSymbolTestCaseData()
{
Environment.CurrentDirectory = "c:\RequiredDirectory";
return new []
{
new TestCaseData("SPY", new Symbol(Security.GenerateEquity("SPY"), "SPY")),
new TestCaseData("EURUSD", new Symbol(Security.GenerateForex("EURUSD"), "EURUSD"))
};
}

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 can I include a mxj Java jar/class folder in a freezed m4l-Device?

I have a maxforlive device using java/mxj.
I used all of these options to include my java files during development:
Including my (maven) target/classes directory through max.java.config.txt.
Adding a directory through Options > File Preferences
Adding a jar to the automatically generated (OSX) ~/Documents/Max 7/Max for Live Devices/MyProject Project/ directory
All of these paths work fine i.e. the files are picked up and my mxj object works.
However, when i freeze the device for publication, java files are not included from any of those paths.
I tried to make sense of
https://docs.cycling74.com/max7/tutorials/jitterchapter99_appendixd although I'm not building a standalone, but a freezed maxforlive device, so I included max.jar and mxj.mxo in the Project folder which did not work either.
When I copy my target/classes or target/classes/myproject folder into the generated Project folder (/code, /code/classes, /classes), max moves all the class files out into /code, creating a lot of work for me while not even picking the classes up for dev.
I saw devices on maxforlive.com with properly included java files, so I know it can be done. How can I achieve this?
Unfortunately this is a long standing bug in MFL.
Here is a movie from 2012 where I reproduce this, it has not been fixed since. http://arttech.nl/projectjavaissue.mov
This means that the only way to distribute MFL devices with java class files is to include them separately.
Ok, so here it is: Including just a single class with no other class dependencies except MaxObject works fine. There's also no need to add .java files like I said in my previous comment.
All you need to do is:
have the working mxj object in your patcher (doesn't matter where you saved it)
click the button on the bottom that says "Show containing project" on hover
add your classfile
freeze
When you have more classes, it gets complicated.
1) If you have your typical java hierarchy with folders and subfolders, that won't work. As you have to add each file separately, the hierarchy will be destroyed. Use a jar and add it to the containing project.
2) Here it comes, believe it or not: All the classes you are going to use will have to be loaded on first instantiation. I call it static class allocation ;)
A way to achieve that:
create a new instance of every class in the constructor of the class that extends MaxObject or any other constructors it calls. That includes classes with only static methods.
if you happen to use interfaces and create implementations of those dynamically (new Runnable() {...}), don't. Dynamic implementations are new classes.
Fun fact: you can override methods of classes, too. So go
class Runner {
public void run() { throw new Exception("not implemented"); }
}
then you can dynamically create a
new Runner() {
public void run() {
MaxObject.post("Even Mr. Gosling says interfaces were a mistake!");
}
}
Don't believe it? I don't blame ya. Look at
https://github.com/mihop/mxj-wsserver
and
http://www.maxforlive.com/library/device/3809
to be converted.

Eclipse JUnit test wizard, creating test methods afterwards

In the wizard for creating a new JUnit Test Case, the second step consist of choosing which methods of the class under test you want to test, and it automatically creates an empty test method in the test class.
If you forgot to do this second step, or accidentally pressed "Finish" instead of "Next", is there a way to create those methods after the test class has been created?
Or the only way to do it is to delete the created test class and repeat the process?

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.