I am starting to use SWTBot to test my application Eclipse RCP v4.
This is my code, to get a part via an id and activate it.
protected static void openPart(final String id) {
Display.getDefault().syncExec(new Runnable() {
public void run() {
EPartService partService = E4Workbench.getServiceContext().getActiveLeaf().get(EPartService.class);
MPart part = partService.findPart(id);
partService.activate(part);
}
});
}
This is my tests. And it doesn't work...
#Test
public void test1() {
openPart("testmaker.part.gauche");
bot.tree().getTreeItem("hju / PQT").expand();
}
#Test
public void test2() {
openPart("testmaker.part.stepRightSide");
bot.button("Add Comment").click();
}
I don't know how to link my private static SWTBot bot; with my RCP Part.
I have already tried with bot.viewby...(name/id/etc).show();, it doesn't work.
This is my RCP application :
Does anyone can help me to use an rcp app with SWTBot ?
I have the solution now.
With the org.eclipse.swtbot.e4.finder plugin and the class SWTWorkbenchBot from this plugin it works.
Related
This is a plugin system which is based on the factory pattern.
Each plugin extends the Plugin class and implements a factory that returns the extended class to the kernel.
Plugins are compiled as shared libraries. Kernel checks the plugins/ directory and loads all libraries at runtime.
When the red button is clicked, the kernel calls call_on_red_click() on every loaded plugin.
// Plugin.h
class Plugin {
public:
virtual void call_on_blue_click() = 0;
virtual void call_on_red_click() = 0;
}
// MyPlugin.h
class MyPlugin : public Plugin {
public:
void call_on_blue_click() {/*[...]*/}
void call_on_red_click() {
// Does something
// Optionaly, activate teleporter
}
}
Plugin *plug_factory() { return new MyPlugin; }
// MyOtherPlugin.h
class MyOtherPlugin : public Plugin {
public:
void call_on_blue_click() {/*[...]*/}
void call_on_red_click() {
// Does something else
// Optionaly, activate teleporter
}
}
Plugin *plug_factory() { return new MyOtherPlugin; }
The teleporter is compiled separately and may not be present in every installation (It's shiped by itself).
Lets say that MyPlugin and MyOtherPlugin want to activate the teleporter if it is present.
Questions:
Should the Teleporter be a kernel Plugin or something else?
Is there a design pattern for this?
Sounds like you want the decorator pattern
Which will allow you to have a class that loads the dll, and then your plugins can then query your decorator if teleportation is enabled. You can then disable it for any reason, not just because the dll isn't there; or enable it even if the dll isn't there but implemented in another way.
I am implementing unit test using TestBrowser. I need to send the configuration to the test browser.
Here is the link of what I want to implement.
I write the code as :
#Test
public void testIndexPageRetrieval() {
running(testServer(testPort, fakeApplication(configuration.asMap())), HTMLUNIT, new Callback<TestBrowser>() {
#Override
public void invoke(TestBrowser browser) {
browser.maximizeWindow();
IndexPage indexPage = new IndexPage(browser.getDriver(), testPort, 0);
browser.goTo(indexPage);
indexPage.isAt();
}
});
}
Unable to import the Callback class. I tried import it manually but play.libs.F.Callback is not available. How do I can use Callback class or is there otherway around for this ?
I´m trying to use MVP to enhance unit testing and run tests faster (because I'm testing logic not android code so I avoid using things like RobotElectric).
But I´m using RXAndroid and it needs Looper to get Schedulers.io() and AndroidSchedulers.mainThread() and when I try to run sometime like
class Phone {
public Observable<> sendSms(String number){
//...
}
}
Phone.getInstance().sendSms(phoneNumber)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(phone -> {
mView.dismissProgress();
mView.startCodeView(phone);
}, error -> {
mView.dismissProgress();
mView.showError(error);
});
I get:
Caused by: java.lang.RuntimeException: Method getMainLooper in android.os.Looper not mocked. See http://g.co/androidstudio/not-mocked for details.
at android.os.Looper.getMainLooper(Looper.java)
at rx.android.schedulers.AndroidSchedulers.<clinit>(AndroidSchedulers.java:27)
... 28 more
I tried:
android {
// ...
testOptions {
unitTests.returnDefaultValues = true
}
}
But it will not work because I want to run full JUnit tests and not Roboelectric or Espresso stuff.
How can I accomplish it? is there any Scheduler that will not crash because of this?
I am also using scheduler thread for this, but in my test SetUp and TearDown.
#Before
public void setUp() throws Exception {
RxAndroidPlugins.getInstance().registerSchedulersHook(new RxAndroidSchedulersHook() {
#Override
public Scheduler getMainThreadScheduler() {
return Schedulers.immediate();
}
});
}
#After
public void tearDown() {
RxAndroidPlugins.getInstance().reset();
}
Will this help?
I ended up adding using transformations and "flavour injection classes" for this, have a class that uses the main for prod/debug releases and use another class in the test flavour folder for testing Schedulers.immediate().
normal flavoured class:
public class Transformer {
public static <T> Observable.Transformer<T, T> applyIoSchedulers() {
return observable -> observable.subscribeOn(getIoScheduler())
.observeOn(getMainScheduler());
}
private static Scheduler getIoScheduler() {
return Schedulers.io();
}
private static Scheduler getMainScheduler() {
return AndroidSchedulers.mainThread();
}
}
Testing flavoured class:
public class Transformer {
public static <T> Observable.Transformer<T, T> applyIoSchedulers() {
return observable -> observable.subscribeOn(getIoScheduler())
.observeOn(getMainScheduler());
}
private static Scheduler getIoScheduler() {
return Schedulers.immediate() ;
}
private static Scheduler getMainScheduler() {
return Schedulers.immediate() ;
}
}
Then use it with transformations:
mSessionRepository.login(...)
.compose(Transformer.applyIoSchedulers())
.subscribe(session -> { })
In our practice, we try to avoid using AndroidSchedulers.mainThread() in Presenter because it's a detail of View implementation. You can do this too.
Though we use Robolectric, so anyway it'll work in our tests.
Yup, no android.jar in junit tests means no Loopers. If you use Dagger you can inject a mock scheduler into tests and a real scheduler into source code. You could also use something like Mockito to mock the Scheduler. Otherwise like #Artem Zinnatullin suggested, Robolectric solves this problem. Robolectric 3 is very easy to setup with Android Studio.
I am trying to create unit test with scout context and I can't find proper tutorial or example for it.
When I create test with ScoutClientTestRunner, I get error
java.lang.Exception: Client session class is not set. Either set the default client session using 'ScoutClientTestRunner.setDefaultClientSessionClass' or annotate your test class and/or method with 'ClientTest'
I try to set client session class like this :
#Before
public void setClassSession() throws Exception {
ScoutClientTestRunner.setDefaultClientSessionClass(ClientSession.class)
}
and
#BeforeClass
public void setClassSession() throws Exception {
ScoutClientTestRunner.setDefaultClientSessionClass(ClientSession.class);
}
I try to add #ClientTest to the class and to all methods but I still get same error.
How to set client session in tests if you use ScoutClientTestRunner ?
The ScoutClientTestRunner ensures that the JUnit tests are executed having all the Scout Context (OSGi and so on) available.
Your attempts with #Before or #BeforeClass are too late. You need to provide the Scout Context initialization parameters before that. As the exception message says, you have 2 possibilities:
(1) #ClientTest annotation
You can annotate test classes or methods with #ClientTest using the clientSessionClass parameter:
#RunWith(ScoutClientTestRunner.class)
#ClientTest(clientSessionClass = ClientSession.class)
public class DesktopFormTest {
#Test
public void test1() throws Exception {
//Do something requiring a scout context:
//for example instantiate a DesktopForm.
}
}
If necessary you can also do it at method level:
#RunWith(ScoutClientTestRunner.class)
public class DesktopFormTest {
#Test
#ClientTest(clientSessionClass = Client1Session.class)
public void test1() throws Exception {
//client session is an instance of Client1Session.
}
#Test
#ClientTest(clientSessionClass = Client2Session.class)
public void test2() throws Exception {
//client session is an instance of Client2Session.
}
}
(2) Defining a TestEnvironment
When the test is run (directly or using maven-tycho), a lookup for a fully qualified class org.eclipse.scout.testing.client.runner.CustomClientTestEnvironment is done.
The CustomClientTestEnvironment class should implement org.eclipse.scout.testing.client.runner.IClientTestEnvironment
The method setupGlobalEnvironment() is called once and can be used to define the default client session with ScoutClientTestRunner.setDefaultClientSessionClass(..). This method can also be used to register required services.
Here an example:
package org.eclipse.scout.testing.client.runner; // <= can not be changed.
// add imports
public class CustomClientTestEnvironment implements IClientTestEnvironment {
#Override
public void setupGlobalEnvironment() {
//Set client session:
ScoutClientTestRunner.setDefaultClientSessionClass(ClientSession.class);
}
#Override
public void setupInstanceEnvironment() {
}
}
Of course (1) and (2) are compatible. The second mechanism defines only the default and ClientSession configured with (1) will override the default.
I have 2 files:
xxxxxTest.java
[refer this]
public class xxxxxTest extends TestCase {
// Run setup only once
public static Test suite() {
TestSetup setup = new TestSetup(new TestSuite(xxxxxTest.class)) {
protected void setUp() throws Exception {
//Some init which i need only once
}
protected void tearDown() throws Exception {
}
};
return setup;
}
public void testMyFirstMethodTest() {
assertNotNull(do stuff here);
}
}
AllTests.java
public class AllTests {
public static Test suite() {
TestSuite suite = new TestSuite("Test for xxxxxx");
//$JUnit-BEGIN$
suite.addTestSuite(xxxxxTest.class);
//$JUnit-END$
return suite;
}
}
So, my individual test(xxxxxTest.java) works fine, exactly as I want.When i run my test suite (AllTests.java), it fails, because the init in setup() i provided in xxxxxTest.java are not being executed.
Any suggestions?
UPDATE
I tried #BeforeClass in JUnit 4. But, it didn't help because in my ssetUp() method, I start an embedded Jetty server (server.start()), the server works fine with the code I posted, but when I do the same with #BeforeClass, it does not work.
In rare cases I also hacked around with static when using JUnit3.
In your case:
give the static{} initializer a try, maybe it works opposed to your static initialization.
if possible upgrade to JUnit4 and use #BeforeClass annotation (it is run once for a test-class). Your other JUnit3 test-classes should be runnable with JUnit4 test-runner also.
Similar to manuel's point: do you -need- to use JUnit 3? Then a class-level static{} initializer might be your best bet.
Otherwise, I recommend using JUnit 4, which has a construct which would might enjoy:
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
public class xxxxxTest {
#BeforeClass
public static void beforeClass() {
//Some init which i need only once
}
#Test
public void testMyFirstMethodTest() {
Assert.assertNotNull("");//do stuff here);
}
}