So I'm testing an eclipse plugin with SWTbot and I'm not getting the result I'm expect - when I cut the test down it turns out that the problem isn't with the bot it's with some code that I've copied accross from another part of the program (where it was fully functional)
The following code...
#RunWith(SWTBotJunit4ClassRunner.class)
public class Tests {
private static SWTWorkbenchBot bot;
#BeforeClass
public static void beforeClass() throws Exception {
bot = new SWTWorkbenchBot();
bot.viewByTitle("Welcome").close();
}
#Test
public void maybeThisWillWork(){
IWorkbenchWindow activeWorkbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
System.out.println("A");
IWorkbenchPage activePage = activeWorkbenchWindow.getActivePage();
System.out.println("B");
}
#AfterClass
public static void sleep() {
System.out.println("In the sleep function");
bot.sleep(10000);
}
}
Gives me the output -
A
In the sleep function
Rather than the expected
A
B
In the sleep function
Any ideas?
you may need to run your test as JUnit plugin test. Have you tried that?
So it turns out that the answer is thus (also a nice advantage of stackoverflow is that I actually solved this somewhere else, remembered I'd had a similar problem and then had to come back to stackoverflow to remind myself of the details)
SWTBot isn't running in the UI thread proper hence the null pointer errors, what I had to do was use effectively:
Display display = bot.getDisplay();
display.syncExec(objectThatdoesthethingiwanttogetdoneintheUIthread);
System.out.println(objectThatdoesthethingiwanttogetdoneintheUIthread.results);
...and that got things working...
Related
My apologies, it is an odd use case but please bear with me.
I have a simple TestFixture (as shown below) that outside of calling a PrimeService to check whether or not a number is prime, logs to a file whenever a routine is hit (ie. OneTimeSetup, Setup, OneTimeTearDown etc.)
Can someone please explain to me why If I run the following scenario, the TestFixture runs in it's entirety?
I place a breakpoint in my Test right before my Assert.
I start a "Debug Tests" process in VS (2019)
When the test pauses (and it will on the first test naturally), I press the "Stop Debugging" button (shift F5)
If I go and open my log file, I will see that all 3 tests ran, as did the TearDowns and final Teardown.
My apologies, I just want to understand what is going on under the hood, and whether or not there is a way to kill a paused Test run.
Thanks.
[TestFixture]
public class PrimeService_IsPrimeShould
{
private NerdAnalysis.PrimeService _primeService;
private System.IO.StreamWriter file;
[OneTimeSetUp]
public void OneTimeSetup()
{
file = new System.IO.StreamWriter(#"C:\Users\Fozzy Bear\source\repos\NunitTutorial\MyFile.txt");
file.WriteLine("One time SetUp");
}
[SetUp]
public void Setup()
{
_primeService = new NerdAnalysis.PrimeService();
file.WriteLine("Setup");
}
[TestCase(-1)]
[TestCase(0)]
[TestCase(1)]
public void IsPrime_lessthan2_pass(int value)
{
file.WriteLine("Running test for value " + value);
var result = _primeService.IsPrime(value);
Assert.IsFalse(result, "${ value} should not be prime");
var breakLine = "break";
Assert.Pass();
}
[OneTimeTearDown]
public void FinalTearDown() {
file.WriteLine("Final Teardown");
file.Close();
file.Dispose();
}
[TearDown]
public void TearDown()
{
file.WriteLine("Tear down");
}
from http://msdn.microsoft.com/en-us/library/406kfbs1.aspx
Stop Debugging terminates the process you are debugging if the program
was launched from Visual Studio. If you attached to the process,
instead of launching it from Visual Studio, the process continues
running. If you want to terminate attached processes, you can
terminate a single process from the Processes window or terminate all
attached process with the Terminate All command.
Consider this Test
[TestFixture]
class Sample
{
[Test]
public void Test()
{
Thread.CurrentThread.Name = "Foo";
}
}
If I debug this test, it passes without error.
If I run this test, it fails with the following exception
System.InvalidOperationException : This property has already been set and cannot be modified.
In run mode, the test's thread's name is "NonParallelWorker".
In debug mode, the test's thread's name is null
As a constraint, assume the code-under-test is not allowed to change, and attempts to set the thread's name, without checking for null first.
E.g.
public void SampleMethodUnderTest()
{
// It is important that this method gets to set this field.
Thread.CurrentThread.Name = "Important Value";
}
My search through the documentation and other's posts has come up dry...
Question
Is there any way to disable/modify NUnit's thread-naming behavior?
Try adding the RequiresThreadAttribute.
[TestFixture]
class Sample
{
[Test, RequiresThread]
public void Test()
{
Thread.CurrentThread.Name = "Foo";
}
}
I think this will work currently, although the fact that this creates an unnamed thread may be an implementation detail, and not something that will necessarily work reliably going forward, I'm not sure. The alternative of course is to create your own user-controlled thread in the test, and pass any exceptions back to NUnit.
Having a test class like this
public class VerySimpleFactory {
#TestFactory
public Stream<? extends DynamicNode> someTests() {
DynamicContainer container1 = DynamicContainer.dynamicContainer("A",
Arrays.asList(t("A1"), t("A2"), t("A3"), t("A4"), t("A5")));
DynamicContainer container2 = DynamicContainer.dynamicContainer("B",
Arrays.asList(t("B1"), t("B2"), t("B3"), t("B4"), t("B5")));
DynamicContainer container3 = DynamicContainer.dynamicContainer("C",
Arrays.asList(t("C1"), t("C2"), t("C3"), t("C4"), t("C5")));
DynamicContainer container4 = DynamicContainer.dynamicContainer("D",
Arrays.asList(t("D1"), t("D2"), t("D3"), t("D4"), t("D5")));
return Arrays.asList(container1, container2, container3, container4).stream();
}
#Test
public void t1() throws Exception {
Thread.sleep(1000);
}
#Test
public void t2() throws Exception {
Thread.sleep(1000);
}
public DynamicTest t(String name) {
return DynamicTest.dynamicTest(name, () -> Thread.sleep(1000));
}
}
the Tests having a #Test annotaiton are discovered instantly by JUnit View, but the tests from TestFactory are discoverd at runtime, each after the last test was completely executed. This leads to a changing and "jumping" JUnit view. Also I cannot select a special test I'm interested in to be executed as single test, until all previous tests were executed.
It would be much nicer if all dynamic tests were shown in JUnit view also at beginning of test execution.
If this doesn't happen, is it a problem of JUnit 5, eclipse or my code?
Dynamic tests are dynamic. Not static.
It is not possible to know before-hand which and how many tests will be generated by #TestFactory annotated method ... actually, it may produce tests in an eternal loop.
Copied from https://junit.org/junit5/docs/current/user-guide/#writing-tests-dynamic-tests-examples
generateRandomNumberOfTests() implements an Iterator that generates
random numbers, a display name generator, and a test executor and then
provides all three to DynamicTest.stream(). Although the
non-deterministic behavior of generateRandomNumberOfTests() is of
course in conflict with test repeatability and should thus be used
with care, it serves to demonstrate the expressiveness and power of
dynamic tests.
For some reason after I had added and removed a static vairable from my code, eclipse started giving me errors on all functions that I call, saying that these functions must be static. However, if I let the program run with these errors, the program runs just as I intended it to do. My Code:
package main;
public class Main implements Runnable {
public void start() {
Thread thread = new Thread(this);
thread.start();
System.out.println("Running...");
Ball.test(); <--- Giving me an error
}
public void run() {
}
public void stop() {
System.out.println("Exiting...");
}
}
and when I create a method in ball called test it gives me:
public static void test() {
// TODO Auto-generated method stub
}
Well yes - you're calling the method as if it were a static method:
Ball.test()
If you want to call an instance method, you need to call it on an instance, e.g.
Ball ball = new Ball();
ball.test();
It's important to understand the difference between static members and instance members. Have you read the appropriate chapter of the Java tutorial? Do you have a good Java book which would help you? (Stack Overflow is great for specific questions, but not good for learning a language from scratch. Explaining language concepts well takes a lot of space and time.)
I need to change status line message from a handler class. After reading the RCP tutorial and eclipse FAQ, I finally did something like this:
HandlerUtil.getActiveWorkbenchWindow(event).getActivePage().findView(AView.ID).getViewSite().getActionBars().getStatusLineManager().setMessage( "Ha, I'm finished");
What a long invoking chain!
Am I doing it the right way? Thanks.
From the threads I see in the forums, that looks about right.
Beware though if you have asynchronous feedback to put in this status line.
See this thread for instance.
UIJob job = new UIJob() {
public IStatus run(IProgressMonitor monitor) {
//do the long running work here
Runnable results = new Runnable() {
public void run(){
// update UI elements here;
getViewSite().getActionBars().getStatusLineManager().
setMessage("End Pasting");
}
};
display.asyncExec(results);
}
};
job.schedule();
(Note: that may be not your case, but I add this code snippet just for information)