Refactored unit tests (#643)

* Removed redundant configureHostInfo
  It was only used to set the Kodi backend version which is also
  set using setKodiMajorVersion.

* Removed unused annotations and throwables

* Improved robustness of SlideUpPanelTests
  Replaced explicit sleeps with the waitForView action.
  Fixed issue in waitForView action as it required the UI
  to be idle which is mostly not the case for the bottom
  panel with the progress indicator.

* Improved robustness of eventserver
  When eventserver handles a wrong payload this should not crash
  but simply show a log message and let the actual test fail.
This commit is contained in:
Martijn Brekhof 2019-06-11 09:47:11 +02:00 committed by Synced Synapse
parent e5ab122b1d
commit d1d8412654
14 changed files with 51 additions and 105 deletions

View File

@ -22,7 +22,6 @@ import android.support.test.espresso.UiController;
import android.support.test.espresso.ViewAction;
import android.support.test.espresso.action.MotionEvents;
import android.support.test.espresso.action.Press;
import android.support.test.espresso.action.ScrollToAction;
import android.support.test.espresso.util.HumanReadables;
import android.support.test.espresso.util.TreeIterables;
import android.support.v4.view.PagerAdapter;
@ -92,7 +91,6 @@ public final class ViewActions {
@Override
public void perform(UiController uiController, View view) {
uiController.loopMainThreadUntilIdle();
final long endTime = System.currentTimeMillis() + millis;
do {
for (View child : TreeIterables.breadthFirstViewTraversal(view)) {

View File

@ -62,12 +62,6 @@ abstract public class AbstractTestClass<T extends AppCompatActivity> {
*/
abstract protected void setSharedPreferences(Context context);
/**
* Called from {@link #setUp()} right after HostInfo has been created.
* @param hostInfo created HostInfo used by the activity under test
*/
abstract protected void configureHostInfo(HostInfo hostInfo);
private LoaderIdlingResource loaderIdlingResource;
private ActivityTestRule<T> activityTestRule;
private static MockTcpServer server;
@ -114,8 +108,6 @@ abstract public class AbstractTestClass<T extends AppCompatActivity> {
hostInfo = Database.addHost(context, server.getHostName(),
HostConnection.PROTOCOL_TCP, HostInfo.DEFAULT_HTTP_PORT,
server.getPort(), useEventServer, kodiMajorVersion);
//Allow each test to change the host info
configureHostInfo(hostInfo);
loaderIdlingResource = new LoaderIdlingResource(activityTestRule.getActivity().getSupportLoaderManager());
IdlingRegistry.getInstance().register(loaderIdlingResource);

View File

@ -79,11 +79,6 @@ public class AddonsActivityTests extends AbstractTestClass<AddonsActivity> {
}
@Override
protected void configureHostInfo(HostInfo hostInfo) {
}
@Before
public void setUp() throws Throwable {
super.setUp();

View File

@ -58,11 +58,6 @@ public class MoviesActivityTests extends AbstractTestClass<MoviesActivity> {
}
@Override
protected void configureHostInfo(HostInfo hostInfo) {
}
/**
* Test if action bar title initially displays Movies
*/

View File

@ -18,7 +18,6 @@ package org.xbmc.kore.tests.ui.movies;
import android.content.Context;
import android.support.test.espresso.Espresso;
import android.support.test.filters.LargeTest;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
@ -26,13 +25,11 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.xbmc.kore.R;
import org.xbmc.kore.host.HostInfo;
import org.xbmc.kore.testhelpers.EspressoTestUtils;
import org.xbmc.kore.tests.ui.AbstractTestClass;
import org.xbmc.kore.ui.sections.video.MoviesActivity;
@RunWith(AndroidJUnit4.class)
@LargeTest
public class RestoreSearchQueryListFragmentTest extends AbstractTestClass<MoviesActivity> {
private final String SEARCH_QUERY = "Room";
@ -53,11 +50,6 @@ public class RestoreSearchQueryListFragmentTest extends AbstractTestClass<Movies
}
@Override
protected void configureHostInfo(HostInfo hostInfo) {
}
/**
* Simple test that checks if search query results in expected item(s)
*/

View File

@ -62,11 +62,6 @@ public class MusicActivityTests extends AbstractTestClass<MusicActivity> {
}
@Override
protected void configureHostInfo(HostInfo hostInfo) {
}
/**
* Test if action bar title initially displays Music
*/

View File

@ -19,7 +19,6 @@ package org.xbmc.kore.tests.ui.music;
import android.app.Activity;
import android.content.Context;
import android.support.test.espresso.Espresso;
import android.support.test.filters.LargeTest;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
@ -27,7 +26,6 @@ import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.xbmc.kore.R;
import org.xbmc.kore.host.HostInfo;
import org.xbmc.kore.testhelpers.EspressoTestUtils;
import org.xbmc.kore.testhelpers.LoaderIdlingResource;
import org.xbmc.kore.tests.ui.AbstractTestClass;
@ -37,7 +35,6 @@ import static org.xbmc.kore.testhelpers.EspressoTestUtils.clickAlbumsTab;
import static org.xbmc.kore.testhelpers.EspressoTestUtils.clickArtistsTab;
@RunWith(AndroidJUnit4.class)
@LargeTest
public class RestoreSearchQueryViewPagerTest extends AbstractTestClass<MusicActivity> {
private final String ARTIST_SEARCH_QUERY = "Ben";
@ -64,11 +61,6 @@ public class RestoreSearchQueryViewPagerTest extends AbstractTestClass<MusicActi
}
@Override
protected void configureHostInfo(HostInfo hostInfo) {
}
/**
* Simple test that checks if search query results in expected item(s)
*

View File

@ -32,7 +32,6 @@ import org.junit.Rule;
import org.junit.Test;
import org.xbmc.kore.R;
import org.xbmc.kore.Settings;
import org.xbmc.kore.host.HostInfo;
import org.xbmc.kore.testhelpers.Utils;
import org.xbmc.kore.testhelpers.action.ViewActions;
import org.xbmc.kore.tests.ui.AbstractTestClass;
@ -75,11 +74,6 @@ public class SlideUpPanelTests extends AbstractTestClass<MusicActivity> {
}
@Override
protected void configureHostInfo(HostInfo hostInfo) {
}
@Override
public void setUp() throws Throwable {
super.setUp();
@ -409,7 +403,12 @@ public class SlideUpPanelTests extends AbstractTestClass<MusicActivity> {
rotateDevice(getActivity());
onView(withId(R.id.vli_seek_bar)).check(matches(withProgress(volume)));
onView(isRoot()).perform(ViewActions.waitForView(R.id.vli_seek_bar, new ViewActions.CheckStatus() {
@Override
public boolean check(View v) {
return ((SeekBar) v).getProgress() == volume;
}
}, 10000));
onView(withId(R.id.vli_volume_text)).check(matches(withText(String.valueOf(volume))));
assertTrue(getApplicationHandler().getVolume() == volume);
}
@ -486,9 +485,14 @@ public class SlideUpPanelTests extends AbstractTestClass<MusicActivity> {
getPlayerHandler().startPlay();
SeekBar seekBar = (SeekBar) getActivity().findViewById(R.id.mpi_seek_bar);
int progress = seekBar.getProgress();
SystemClock.sleep(1000); //wait one second to check if progression has indeed progressed
assertTrue(seekBar.getProgress() > progress);
final int progress = seekBar.getProgress();
onView(isRoot()).perform(ViewActions.waitForView(
R.id.mpi_seek_bar, new ViewActions.CheckStatus() {
@Override
public boolean check(View v) {
return ((SeekBar) v).getProgress() > progress;
}
}, 10000));
}
/**
@ -502,11 +506,15 @@ public class SlideUpPanelTests extends AbstractTestClass<MusicActivity> {
public void progressionUpdaterStartedAfterPlay() {
expandPanel();
SeekBar seekBar = (SeekBar) getActivity().findViewById(R.id.mpi_seek_bar);
int progress = seekBar.getProgress();
final int progress = seekBar.getProgress();
SystemClock.sleep(1000); //wait one second to check if progression has indeed progressed
assertTrue(seekBar.getProgress() > progress);
onView(isRoot()).perform(ViewActions.waitForView(
R.id.mpi_seek_bar, new ViewActions.CheckStatus() {
@Override
public boolean check(View v) {
return ((SeekBar) v).getProgress() > progress;
}
}, 10000));
}
/**

View File

@ -37,8 +37,6 @@ import org.xbmc.kore.testutils.eventserver.EventPacketBUTTON;
import org.xbmc.kore.testutils.eventserver.MockEventServer;
import org.xbmc.kore.ui.sections.remote.RemoteActivity;
import java.io.IOException;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.action.ViewActions.longClick;
@ -62,13 +60,8 @@ public class ButtonTests extends AbstractTestClass<RemoteActivity> {
Utils.setUseEventServerPreference(context, true);
}
@Override
protected void configureHostInfo(HostInfo hostInfo) {
}
@BeforeClass
public static void setupEventServer() throws Throwable {
public static void setupEventServer() {
mockEventServer = new MockEventServer();
mockEventServer.setListenPort(HostInfo.DEFAULT_EVENT_SERVER_PORT);
mockEventServer.start();
@ -86,40 +79,40 @@ public class ButtonTests extends AbstractTestClass<RemoteActivity> {
}
@AfterClass
public static void cleanup() throws IOException {
public static void cleanup() {
mockEventServer.shutdown();
}
@Test
public void leftControlPadButtonTest() throws InterruptedException {
public void leftControlPadButtonTest() {
onView(withId(R.id.left)).perform(click());
testRemoteButton(ButtonCodes.REMOTE_LEFT);
}
@Test
public void rightControlPadButtonTest() throws InterruptedException {
public void rightControlPadButtonTest() {
onView(withId(R.id.right)).perform(click());
testRemoteButton(ButtonCodes.REMOTE_RIGHT);
}
@Test
public void upControlPadButtonTest() throws InterruptedException {
public void upControlPadButtonTest() {
onView(withId(R.id.up)).perform(click());
testRemoteButton(ButtonCodes.REMOTE_UP);
}
@Test
public void downControlPadButtonTest() throws InterruptedException {
public void downControlPadButtonTest() {
onView(withId(R.id.down)).perform(click());
testRemoteButton(ButtonCodes.REMOTE_DOWN);
}
@Test
public void selectPadButtonTest() throws InterruptedException {
public void selectPadButtonTest() {
onView(withId(R.id.select)).perform(click());
testRemoteButton(ButtonCodes.REMOTE_SELECT);
@ -128,14 +121,14 @@ public class ButtonTests extends AbstractTestClass<RemoteActivity> {
//The following tests do not use the event server. They're included here
//to make sure they still work when the event server is enabled.
@Test
public void contextControlPadButtonTest() throws InterruptedException {
public void contextControlPadButtonTest() {
onView(withId(R.id.context)).perform(click());
TestUtils.testHTTPEvent(Input.ExecuteAction.METHOD_NAME, Input.ExecuteAction.CONTEXTMENU);
}
@Test
public void infoControlPadButtonTest() throws InterruptedException {
public void infoControlPadButtonTest() {
HostManager.getInstance(getActivity()).getHostInfo().setKodiVersionMajor(17);
onView(withId(R.id.info)).perform(click());
@ -144,21 +137,21 @@ public class ButtonTests extends AbstractTestClass<RemoteActivity> {
}
@Test
public void infoControlPadButtonLongClickTest() throws InterruptedException {
public void infoControlPadButtonLongClickTest() {
onView(withId(R.id.info)).perform(longClick());
TestUtils.testHTTPEvent(Input.ExecuteAction.METHOD_NAME, Input.ExecuteAction.PLAYERPROCESSINFO);
}
@Test
public void osdControlPadButtonTest() throws InterruptedException {
public void osdControlPadButtonTest() {
onView(withId(R.id.osd)).perform(click());
TestUtils.testHTTPEvent(Input.ExecuteAction.METHOD_NAME, Input.ExecuteAction.OSD);
}
@Test
public void backControlPadButtonTest() throws InterruptedException {
public void backControlPadButtonTest() {
onView(withId(R.id.back)).perform(click());
TestUtils.testHTTPEvent(Input.Back.METHOD_NAME, null);

View File

@ -33,8 +33,6 @@ import org.xbmc.kore.tests.ui.AbstractTestClass;
import org.xbmc.kore.testutils.eventserver.MockEventServer;
import org.xbmc.kore.ui.sections.remote.RemoteActivity;
import java.io.IOException;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.action.ViewActions.longClick;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
@ -57,12 +55,8 @@ public class KodiPreV17Tests extends AbstractTestClass<RemoteActivity> {
Utils.setUseEventServerPreference(context, true);
}
@Override
protected void configureHostInfo(HostInfo hostInfo) {
}
@BeforeClass
public static void setupEventServer() throws Throwable {
public static void setupEventServer() {
mockEventServer = new MockEventServer();
mockEventServer.setListenPort(HostInfo.DEFAULT_EVENT_SERVER_PORT);
mockEventServer.start();
@ -80,14 +74,12 @@ public class KodiPreV17Tests extends AbstractTestClass<RemoteActivity> {
}
@AfterClass
public static void cleanup() throws IOException {
public static void cleanup() {
mockEventServer.shutdown();
}
@Test
public void infoControlPadButtonLongClickTest() throws InterruptedException {
HostManager.getInstance(getActivity()).getHostInfo().setKodiVersionMajor(16);
public void infoControlPadButtonLongClickTest() {
onView(withId(R.id.info)).perform(longClick());
String actionReceived = getInputHandler().getAction();

View File

@ -50,10 +50,6 @@ public class ButtonTests extends AbstractTestClass<RemoteActivity> {
Utils.setUseEventServerPreference(context, false);
}
@Override
protected void configureHostInfo(HostInfo hostInfo) {
}
@Override
public void setUp() throws Throwable {
setKodiMajorVersion(HostInfo.KODI_V17_KRYPTON);

View File

@ -48,11 +48,6 @@ public class KodiPreV17Tests extends AbstractTestClass<RemoteActivity> {
Utils.setUseEventServerPreference(context, false);
}
@Override
protected void configureHostInfo(HostInfo hostInfo) {
hostInfo.setKodiVersionMajor(16);
}
@Override
public void setUp() throws Throwable {
setKodiMajorVersion(HostInfo.KODI_V16_JARVIS);

View File

@ -61,11 +61,6 @@ public class TVShowsActivityTests extends AbstractTestClass<TVShowsActivity> {
}
@Override
protected void configureHostInfo(HostInfo hostInfo) {
}
/**
* Test if action bar title initially displays TV Shows
*/

View File

@ -16,9 +16,12 @@
package org.xbmc.kore.testutils.eventserver;
import org.xbmc.kore.utils.LogUtils;
import java.nio.ByteBuffer;
public class EventPacketBUTTON extends EventPacket {
private final static String TAG = LogUtils.makeLogTag(EventPacketBUTTON.class);
private short code;
private String mapName;
@ -34,14 +37,19 @@ public class EventPacketBUTTON extends EventPacket {
super(packet);
byte[] payload = getPayload();
code = ByteBuffer.wrap(payload, 0, 2).getShort();
flags = ByteBuffer.wrap(payload, 2, 2).getShort();
amount = ByteBuffer.wrap(payload, 4, 2).getShort();
mapName = getStringFromPayload(payload, 6);
try {
code = ByteBuffer.wrap(payload, 0, 2).getShort();
flags = ByteBuffer.wrap(payload, 2, 2).getShort();
amount = ByteBuffer.wrap(payload, 4, 2).getShort();
int nextStringPosition = 6 + mapName.getBytes().length + 1;
buttonName = getStringFromPayload(payload, nextStringPosition);
mapName = getStringFromPayload(payload, 6);
int nextStringPosition = 6 + mapName.getBytes().length + 1;
buttonName = getStringFromPayload(payload, nextStringPosition);
} catch (ArrayIndexOutOfBoundsException e) {
LogUtils.LOGE(TAG, "Error handling payload " + new String(payload));
}
}
public String getButtonName() {