I create test project. My steps:
File - New -Project;
Choose - Android Test Project;
Set name's project;
Choose project when I want test;
Choose SDK target version;
Click Finish.
Done, I create libs folder and add to it espresso-1.0-SNAPSHOT-bundled.jar. Project's structure looks
Done, I create test class:
public class TestT extends ActivityInstrumentationTestCase2<MainActivity>
{
public TestT(Class<MainActivity> activityClass)
{
super(activityClass);
}
#BeforeClass
public static void setUpBeforeClass() throws Exception
{}
#AfterClass
public static void tearDownAfterClass() throws Exception
{}
#Before
public void setUp() throws Exception
{}
#After
public void tearDown() throws Exception
{}
#Test
public void test()
{
fail("Not yet implemented");
}
#SmallTest
public void testTest()
{
Espresso.onView(ViewMatchers.withId(R.id.btnClick)).perform(ViewActions.click());
Espresso.onView(ViewMatchers.withId(R.id.tvClick)).check(ViewAssertions.matches(ViewMatchers.withText(MainActivity.TEXT)));
}
}
Done, I run test project:
Right click on test project;
Run as - Android JUnit project;
Project is run, but it isn't any displaying.
I open Window - Show View - Java - JUnit:
Double click on emulator-5554 show me dialog:
I try in all version's Eclipse and ADT Plugin. What am I doing wrong?
You are using JUnit 4. You must use JUnit 3 as Espresso is based on Android Instrumentation which currently only supports JUnit 3. To do this:
Remove the JUnit 4 reference from the project
Update syntax of test cases to Junit 3 i.e. remove the #Test annotations and update your test methods to be prefixed with the word "test"
Example:
Incorrect
#Test
public void test()
{
fail("Not yet implemented");
}
Example:
Correct
public void test()
{
fail("Not yet implemented");
}
You need to use GoogleInstrumentationTestRunner. See instructions here: https://code.google.com/p/android-test-kit/wiki/Espresso#Espresso_Setup_Instructions
Also, change your test class constructor to this:
public TestT()
{
super(MainActivity.class);
}
Related
Using: Cucumber-JVM with Android Instrumentation + Espresso).
Reference Github link: https://github.com/mfellner/cucumber-android for this. The simple sample works fine.
Problem with cucumber-jvm + android instrumentation:
But in the sample in link, it uses ActivityInstrumentationTestCase2 which is deprecated. I would like to use #Rule - ActivityTestRule class as said by Google.
Here my question is:
For using cucumber-jvm, I am using the CucumberInstrumentationCore instead of
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner".
So Android junit annotations like #Rule for ActivityTestRule is not parsed by CucumberInstrumentation. So Is it possible to overcome this problem?
Then is my decision to use cucumber-jvm + android instrumentation has to be reverted back. My question is not only for the deprecated class but globally is it good idea to go for cucumber-jvm + android instrumentation, as it can't use instrumentation features because of annotation parsing.
Your runner should inherit from Android JUnitRunner:
public class Instrumentation extends AndroidJUnitRunner {
private final CucumberInstrumentationCore instrumentationCore = new CucumberInstrumentationCore(this);
#Override
public void onCreate(final Bundle bundle) {
instrumentationCore.create(bundle);
super.onCreate(bundle);
}
#Override
public void onStart() {
waitForIdleSync();
instrumentationCore.start();
}
Pay attention to the super class been initialized at the end of onCreate.
Then, edit your defaultConfig in your build.grade file:
defaultConfig {
applicationId "your.package.name"
testApplicationId "your.steps.package"
testInstrumentationRunner "your.package.Instrumentation"
}
And finally, the steps definition class, which inherited from ActivityInstrumentationTestCase2 should look like:
public class BaseStepDefinitions {
public static final String TAG = BaseStepDefinitions.class.getSimpleName();
#Rule
public ActivityTestRule<StartupActivity> mActivityRule = new ActivityTestRule<>(StartupActivity.class);
#Before
public void setUp() throws Exception {
mActivityRule.launchActivity(null);
mActivityRule.getActivity();
}
/**
* All the clean up of application's data and state after each scenario must happen here
*/
#After
public void tearDown() throws Exception {
}
#When("^I login with \"([^\"]*)\" and \"([^\"]*)\"$")
public void i_login_with_and(String user, String password) throws Throwable {
// Login...
}
The setUp function runs before each scenario, and launching the activity.
Globally, if it serves your needs I don't see any problem using it like so, both Cucumber annotations and the JUnit annotations can be parsed in this way.
I've created a sample project: github.com/Clutcha/EspressoCucumber
I'm trying out Android development, but haven't come too far because I'm unable to get a test case to fail.
I have the following test case in the androidTest folder:
package com.example.aaronf.myapplication;
import android.test.*;
public class ToDoListTest extends AndroidTestCase {
private void newToDoListHasNoItems() {
assertEquals(new ToDoList().length, 0);
}
private void addingToDoGivesLengthOfOne() {
ToDoList toDoList = new ToDoList();
toDoList.add(new ToDo());
assertEquals(toDoList.length, 1);
}
public void runTests() {
newToDoListHasNoItems();
addingToDoGivesLengthOfOne();
}
public ToDoListTest() {
super();
runTests();
}
}
The ToDoList class looks like:
package com.example.aaronf.myapplication;
public class ToDoList {
public int length = 0;
public void add(ToDo toDo) {
}
}
It seems like it should fail on addingToDoGivesLengthOfOne(), but I get a green bar.
EDIT
I should add that adding #Test annotations to the methods generates a symbol not found error.
EDIT
I visited the suggested post My Junit test doesn't run. However, there is a difference with my problem. My methods used to have the test prefix, but this didn't affect the outcome. Also, the #Test annotation, as I mentioned before, is flagged with an error: "Cannot resolve symbol Test".
The problem was that my Test Artifact was set to Android Instrumentation Tests instead of Unit Tests. Since my unit tests were being added to the Android Instrumentation group, the unit testing stuff wasn't being recognized.
I am using Android Studio to try and test my activity. Here is the basic code:
public class MyActivityTest extends ActivityUnitTestCase<MyActivity> {
public MyActivityTest() {
super(MyActivity.class);
}
#Override
protected void setUp() throws Exception {
super.setUp();
}
#SmallTest
public void testSomething() {
Assert.assertNotNull("something is null", null);
}
}
I would expect that this test case fails. Everything I try passes though. This seems like a strange question, but how can I make my test case fail? What am I doing wrong?
I managed to get this working, sort of. I found this on a bug report:
We are in the process of deprecating ActivityUnitTestCase. We recommend to move business logic to a separate class and unit test it with gradle unit test support (mockable android.jar).
So I extended ActivityInstrumentationTestCase2 instead and ran the test as an Instrumentation Test rather than a Unit Test. That worked. Here is basically what I have now:
public class MyActivityTest extends ActivityInstrumentationTestCase2<MyActivity> {
public MyActivityTest() {
super(MyActivity.class);
}
public void testSomething() throws Exception {
//test goes here
Assert.assertEquals(message, expectedObject, actualObject);
}
}
I'm still not sure why I was seeing the behavior I was earlier, but at least I can test now. Here is a screenshot of my Test Build Configuration:
I am currently upgrading robolectric from version 1 to 2. In my current version I use the following to provide the test module (for binding) to roboguice.
public class RoboTestRunner extends RobolectricTestRunner {
public RoboTestRunner(Class<?> testClass) throws
InitializationError {
super(testClass);
}
#Override
public void prepareTest(Object test) {
Application app = Robolectric.application;
RoboGuice.setBaseApplicationInjector(app, RoboGuice.DEFAULT_STAGE,
Modules.override(RoboGuice.newDefaultRoboModule(app)).with(new
TestModule()));
Injector injector = RoboGuice.getInjector(app);
injector.injectMembers(test);
}
}
However now I have upgraded the prepareTest method is not in this class. Where should I run this code in the new version?
UPDATE
I have found the way to do this. I need to create an class which extends android.app.Application in the project and reference this in the Manifest. Then I create a class like so
public class TestApplication extends Application implements TestLifecycleApplication {
#Override
public void onCreate() {
super.onCreate();
RoboGuice.setBaseApplicationInjector(this, RoboGuice.DEFAULT_STAGE,
RoboGuice.newDefaultRoboModule(this), new TestModule());
}
#Override
public void beforeTest(Method method) {}
#Override
public void prepareTest(Object test) {
TestApplication application = (TestApplication) Robolectric.application;
RoboGuice.setBaseApplicationInjector(application, RoboGuice.DEFAULT_STAGE,
RoboGuice.newDefaultRoboModule(application), new TestModule());
RoboGuice.getInjector(application).injectMembers(test);
}
#Override
public void afterTest(Method method) {}
}
As this class has Test at the start robolectric should automatically find it and use it. However this doesn't seem to be happening. Does anybody know why?
UPDATE 2
This blog would suggest that the testmodule needs to be in the same package however I have all tests in a different package. How do I work around this?
Your TestApplication class should extend your own Application class, not android.app.Application, and it should be in the same package as your Application.
... however I have all tests in a different package.
That shouldn't be a problem. Put your TestApplication in your test module, but use the package from Application.
e.g., if you're using maven, the files would live here:
src/main/java/com/example/Application.java
src/test/java/com/example/TestApplication.java
I'm writing many tests for my Android application, meaning that there are about 15 tests cases. how can I implement them all? I tried to make several .java files in the same project for each testcase, but it ran only the first one. Then I made one Test,java and wrote several method inside it. like public void test1() throws Exception{...} public void test2() throws Exception{...} . But it also ran just the first test case. In Run Configurations I chose Run all tests in the selected project, while running I could see them all under JUnit window on the left part of the screen, it successfully ran the first, showed that the next is in process but it did nothing((((
Remember to use solo.finishOpenedActivities() in your tearDown(). Then the execution will not hang.
if you are using robotium to perform black box testing this is how ur class should look like:
public class TestAPK extends ActivityInstrumentationTestCase2 {
private static final String TARGET_PACKAGE_ID="com.android.example";//your package name
private static final String LAUNCHER_ACTIVITY_FULL_CLASSNAME="com.android.example.MainActivity"; //your main activity full class name
private static Class launcherActivityClass;
static{
try{
launcherActivityClass=Class.forName(LAUNCHER_ACTIVITY_FULL_CLASSNAME);
}catch(ClassNotFoundException e){
throw new RuntimeException(e);
}
}
public TestAPK() throws ClassNotFoundException{
super(TARGET_PACKAGE_ID,launcherActivityClass);
}
private Solo solo;
protected void setUp() throws Exception{
solo=new Solo(getInstrumentation(),getActivity());
}
public void test1() throws Exception{...}
public void test2() throws Exception{...}
}