Я работал над простым примером использования SeekBar, и у меня возникают проблемы с тем, чтобы мой тест Espresso работал. Когда я запускаю тесты, я могу увидеть движение SeekBar на экране эмулятора, но, по-видимому, он не вызывает OnSeekBarChangeListener, потому что TextView не изменяет значение («Hello World!» - это начальное значение). Если я запустил программу и проверил ее вручную, TextView обновится, как я ожидаю.Тест на поисковую систему, не вызывающий OnSeekBarChangeListener
Основная программа:
package edu.eku.styere.seekbar;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
public class MainActivity extends Activity {
private int cur_progress = 0;
boolean running = false;
final int SEEK_MAX = 100;
final int DELAY_MILLIS = 200;
private TextView mProgressLabel;
private SeekBar mProgressBar;
// message handler
private Handler mHandler = new Handler();
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// fetch items
mProgressLabel = (TextView) findViewById(R.id.progress_text);
mProgressBar = (SeekBar) findViewById(R.id.progress_seekbar);
Button startButton = (Button) findViewById(R.id.btn_start);
startButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// start the timer/progresss bar
cur_progress = 0;
running = true;
// start messages
mHandler.postDelayed(mUpdateTimeTask, DELAY_MILLIS);
}
});
// respond to changes in the seek bar by the user
mProgressBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
public void onProgressChanged(SeekBar sb, int progress, boolean fromUser) {
// user change or from us?
if (fromUser) {
// user changed the bar, so get a new value
cur_progress = progress;
// update the text box
mProgressLabel.setText("progress: " + cur_progress);
mHandler.removeCallbacks(mUpdateTimeTask);
if (running)
mHandler.postDelayed(mUpdateTimeTask, DELAY_MILLIS);
}
}
// need to have these, but not using them here
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
});
}
// the runnable object that corresponds to our timer
private Runnable mUpdateTimeTask = new Runnable() {
public void run() {
// done?
if (cur_progress >= SEEK_MAX) {
// stop everything
mHandler.removeCallbacks(mUpdateTimeTask);
running = false;
return;
}
// update the progress
cur_progress++;
// update the text box
mProgressLabel.setText("progress: " + cur_progress);
// update the seek bar (does not cause onChange event)
mProgressBar.setProgress(cur_progress);
//do this again
mHandler.postDelayed(this, DELAY_MILLIS);
}
}; // mUpdateTimeTask
}
Код проверки:
package edu.eku.styere.seekbar;
import android.app.Instrumentation;
import android.os.SystemClock;
import android.support.test.InstrumentationRegistry;
import android.support.test.espresso.UiController;
import android.support.test.espresso.ViewAction;
import android.support.test.espresso.action.CoordinatesProvider;
import android.support.test.espresso.action.GeneralSwipeAction;
import android.support.test.espresso.action.Press;
import android.support.test.espresso.action.Swipe;
import android.support.test.espresso.matcher.ViewMatchers;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import android.test.InstrumentationTestCase;
import android.view.MotionEvent;
import android.view.View;
import android.widget.SeekBar;
import org.hamcrest.Matcher;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.Random;
import static android.support.test.espresso.Espresso.onView;
import static android.support.test.espresso.action.ViewActions.click;
import static android.support.test.espresso.assertion.ViewAssertions.matches;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.matcher.ViewMatchers.withText;
@RunWith(AndroidJUnit4.class)
public class MainActivityTest {
//Random rng = new Random();
@Rule
public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(MainActivity.class);
@Test
public void moveSeekBar() {
onView(withId(R.id.progress_seekbar)).perform(setProgress(35));
// Check that the text was changed
onView(withId(R.id.progress_text))
.check(matches(withText("progress: " + 35)));
}
public static ViewAction setProgress(final int progress) {
return new ViewAction() {
@Override
public void perform(UiController uiController, View view) {
SeekBar seekBar = (SeekBar) view;
seekBar.setProgress(progress);
}
@Override
public String getDescription() {
return "Set a progress on a SeekBar";
}
@Override
public Matcher<View> getConstraints() {
return ViewMatchers.isAssignableFrom(SeekBar.class);
}
};
}
}
Результат неудачного теста:
android.support.test.espresso.base.DefaultFailureHandler$AssertionFailedWithCauseError: 'with text: is "progress: 35"' doesn't match the selected view.
Expected: with text: is "progress: 35"
Got: "TextView{id=2131165185, res-name=progress_text, visibility=VISIBLE, width=480, height=29,
has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=false, is-enabled=true,
is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false,
root-is-layout-requested=false, has-input-connection=false, x=0.0, y=72.0,
text=Hello world!, input-type=0, ime-target=false, has-links=false}"
...
Добавьте небольшую задержку 0,5 сек для обеспечения того, чтобы тест не прерывался из-за состояния гонки или чего-то еще. – Shark
Не думал о состоянии гонки, но даже 5-секундная задержка ничего не меняет :( –