I am working on an Android app. It has corresponding spec/test application. As part of some of my tests, I need to pick up an image from my assets folder and calculate SHA-1 for it.
I can calculate SHA, as long as I can pick the image. Since the tests run on emulator; I am not sure how to pick the image in my test.
Does anyone have any idea, how I can go about it. With and without AssetManager maybe? Any ideas will be helpful.
Cheers
-Priyank
I do this by extending ActivityInstrumentationTestCase2, then in the setup getting a reference to the activity and finally getting the AssetManager.
public class Sha1Test
extends ActivityInstrumentationTestCase2<MyActivity> {
private AssetManager m_assetManager;
public Sha1Test() {
super("com.example.test", MyActivity.class);
}
#Override
public void setUp() throws Exception {
super.setUp();
MyActivity activity = this.getActivity();
m_assetManager = activity.getAssets();
}
#Override
public void testSomething() throws Exception {
InputStream stream = m_assetManager.open("myimage.png");
}
}
You'll need to run this on the emulator as an Android Unit Test, since it depends on the main activity to load the assets.
Related
I have a helper class to generate screenshots when using Espresso. Screenshots are generated by using Firebase ScreenShotter. My code is as follows:
private static ActivityScenario activityScenario;
public static void setup(){
activityScenario = ActivityScenario.launch(MainActivity.class);
}
public static void screenshot(String name){
activityScenario.onActivity(activity->{
ScreenShotter.takeScreenshot(name, activity /* activity */);
});
}
So another class would call it like this:
#Before
public void setup(){
SetupHelper.setup();
}
#Test
public void loginAfterReset() {
SetupHelper.screenshot("Home");
}
The screenshots do save to the SD card of the device. However, the name of the screenshot on the SD card is:
UnknownTestClass-unknownTestMethod-Home-1.jpg
Why does it come up as UnknowntestClass-unknownTestMethod? How do I have more control over the naming?
ScreenShotter uses the stack trace to figure out the filename, based on the test class and test method that it can find in the stack trace.
ActivityScenario.onActivity() runs the passed action on the current Activity's main thread. Tests are executed on a different thread. So, the action that you pass will have a Stack trace that doesn't include the test method or test class in it. That's the reason why you see UnknownTestClass-unknownTestMethod. When the anonymous function is executed, it's not running "in the context" of the test class.
One way to fix this is not using onActivity(). ActivityScenario.launch() should already bring your Activity into the "resumed" state, i.e. make it visible. Change your SetupHelper.screenshot() to the following:
public static void screenshot(String name){
ScreenShotter.takeScreenshot(name, activity /* activity */);
}
This will change the screenshot filename to include the actual test class and test method name.
Does anyone try to do black-box testing with Android Espresso?
Could anyone provides me with some simple example?
I had tried some example before, but failed every time!
Example, I had tried this one:
public class ApplicationTest extends ActivityInstrumentationTestCase2
{
private static final String ACTIVITY_CLASSNAME = "com.example.kai_yu.blackboxtest";
private static Class launchActivityClass;
static
{
try
{
launchActivityClass = Class.forName(ACTIVITY_CLASSNAME);
}
catch (ClassNotFoundException e)
{
throw new RuntimeException(e);
}
}
public ApplicationTest()
{
super(launchActivityClass);
}
#Test
public void testClick()
{
}
}
But Android Studio said:
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.example.kai_yu.blackboxtest"
com.example.kai_yu.blackboxtest is applicationId which is another installed application on my phone
Thank you!
Espresso can only run as part of an instrumentation test.
Instrumentation tests can only act upon the app under test ( i.e. the target of the instrumentation ).
UIAutomator might be better for your use case.
https://developer.android.com/tools/testing-support-library/index.html#UIAutomator
In Espresso docs you would find this line:
While it can be used for black-box testing, Espresso's full power is unlocked by those who are familiar with the code base under test."
For that reason Espresso testing is called by gray-box testing.
If you're not familiar with programming in Java or Android, or you want just to write black-box testing in the clearest way as possible try to learn instead of Espresso this framework
Calabash-iOS and Calabash-Android are the underlying low-level libraries that empower the Cucumber tool to run automated functional tests on Android...
Website: https://calaba.sh/
GitHub: https://github.com/calabash
Here would you find how and why to start using this framework:
http://blog.teddyhyde.com/2013/11/04/a-better-way-to-test-android-applications-using-calabash/
#RunWith(AndroidJUnit4.class)
#LargeTest
public class EspressoTest1 extends ActivityInstrumentationTestCase2<MainActivity>{
public EspressoTest1() {
super(MainActivity.class);
}
#Before
public void setUp() throws Exception {
super.setUp();
injectInstrumentation(InstrumentationRegistry.getInstrumentation());
}
#Test
public void test1ChatId() {
getActivity();
onView(withId(R.id.anuja)).check(matches(isDisplayed()));
}
#After public void tearDown() throws Exception {
super.tearDown();
}
}
There are two ways to write Espresso Test case one is as per shown above
The Examples are taken from this blog
http://qaautomated.blogspot.in/p/blog-page.html
Where you can find details of hot to run the espresso test case in detail.
When i am wrtting
#Before
public void setUp() throws Exception {
Activity activity = Robolectric.buildActivity(ActivityMain.class).create().get();
}
and after running the test Its giving me error org.fest.reflect.exception.ReflectionError: Unable to find method '$$robo$getData' I am using eclipse and ant build for testing the robolectric test for android.
But this code is working fine with my test
#Test
public void testBasicResourceValue() throws Exception {
String helloFromActivity = new ActivityMain().getResources().getString(R.string.str_my_file);
assertThat(helloFromActivity, equalTo("newfile"));
}
so its confirmed that the program is able to get the AndroidManifest.xml
Activity activity =
Robolectric.buildActivity(ActivityMain.class).create().get(); this
line is not working with ANT build i dont know why? i heard
robolectric is stopped supporting ANT.So i found a another workaround
for this problem to get the shadow object of the activity by using
this code given below
#Before
public void setUp() throws Exception {
MyActivity activity = new MyActivity();
//Remember setContentView() has to call before you are trying to get any resource ID from the activity like Button,TextView etc other wise you will get the not shadow object for those views.
activity.setContentView(R.layout.warning);
Assert.assertNotNull(activity);
}
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{...}
}
This is really looks like some magic is going on and I'm interested to understand why that happens :)
Here's the unit-test I have:
public class SelectThemeActivityTest
extends ActivityInstrumentationTestCase2<SelectThemeActivity> {
private final static int[] STATIC_ARRAY = { 0, 1, 2 };
public SelectThemeActivityTest() {
super("com.the7art.simplewallpaper", SelectThemeActivity.class);
}
#Override
protected void setUp() throws Exception {
super.setUp();
// some array usage here - will throw NullPointerEcxeption on second test
// see description below
STATIC_ARRAY[0] = 2;
}
#Override
protected void tearDown() throws Exception {
super.tearDown();
}
public void testFirst() {
}
public void testSecond() {
}
public void testThird() {
}
}
If I run this test case the first test completes successfully and all the rest fail by throwing NullPointerException from setUp() - the line which tries to access STATIC_ARRAY.
What puzzles me even more is the fact that if I change the test case to extend AndroidTestCase instead of ActivityInstrumentationTestCase2, then all tests complete successfully! Magic! :-)
Also if I remove 'static' keyword from STATIC_ARRAY, tests succeed too.
So it's clear that something is modifying my STATIC_ARRAY by making it null between a test runs, most probably in tearDown() and that something has to do with ActivityInstrumentationTestCase2, but how to track that something? :-) Any ideas?
The reason is scrubClass() method called from super.tearDown(): google-groups discussion. A solution is - overriding this method.
Put a watch point on STATIC_ARRAY and see who modifies it, although there are not too many candidates (since the field is private, there is pretty much only one candidate, the class you just posted, so something is missing from the picture.