Сводка обучения по модульному тестированию #Android «Предлагаемая коллекция»
Сводка обучения по модульному тестированию #Android «Предлагаемая коллекция»

Всем привет, мы снова встретились, я ваш друг Цюаньчжаньцзюнь.

Каталог статей

AndroidединицатестВ основном делятся на следующие два типа

  • локальный модульный тест (Junit Test), Локальный модульный тест — это тест чистого Java-кода. Он работает только в среде JVM локального компьютера и не зависит от какого-либо API платформы Android. Таким образом, скорость выполнения высокая,Более высокая эффективность,Но не могу протестировать код, связанный с Android.
  • Инструментарийтест (Android Test),Это тест кода, связанного с Android.,Необходимо запустить существующее на реальном устройстве или эмуляторе.,Работает медленнее,Но может ли тестирование взаимодействия с пользовательским интерфейсом и доступ к информации об устройстве?,Получите результаты, близкие к реальным.

на При создании нового проекта в Android Studio,appизgradleбудет добавлен по умолчаниюединицатестиз Связанные зависимости Библиотека:

Язык кода:javascript
копировать
dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' }

вtestImplementationдобавить виз Зависимостьместныйизменятьтест Библиотека, androidTestImplementation Добавленная зависимость — это тестовая библиотека в среде Android. При этом в каталоге проекта по умолчанию будет создана тестовая директория:

вapp/src/test/Магазин нижеиздаJunitместныйтесткод,app/src/androidTest/Магазин нижеиздаAndroidтесткод。

1. Локальное модульное тестирование

Чтобы провести локальное модульное тестирование, вам необходимо сначала понять некоторые основные аннотации Junit:

Название аннотации

значение

@Test

Определенный метод является методом модульного тестирования, и этот метод должен быть общедоступным и недействительным.

@Before

Определенный метод выполняется один раз перед выполнением каждого тестового примера и используется для подготовки тестовой среды (например, инициализации класса, чтения входного потока и т. д.). В тестовом классе будет выполняться каждый метод @Test. вызвать звонок.

@After

Определенный метод выполняется один раз после выполнения каждого тестового примера для очистки данных тестовой среды. В тестовом классе выполнение каждого метода @Test вызывает вызов.

@BeforeClass

Определенный метод запускается один раз перед запуском всех вариантов использования в тестовом классе. Метод должен быть public static void, который используется для выполнения некоторых трудоемких работ по инициализации (например, подключения к базе данных).

@AfterClass

Определенный метод запускается один раз после выполнения всех вариантов использования в тестовом классе. Метод должен быть public static void, который используется для очистки данных (например: отключение подключений к данным).

@Test (expected = Exception.class)

Если метод тестирования не выдает тип Exception в аннотации (подклассы также приемлемы), тест не пройден.

@Test(timeout=100)

Если метод тестирования занимает более 100 миллисекунд, тест не пройден и используется для тестирования производительности.

@Ignore или @Ignore («слишком много времени»)

Игнорировать текущий метод тестирования. Обычно он используется, когда метод тестирования не готов или требует слишком много времени.

@FixMethodOrder

Все тестовые методы в тестовом классе, в котором находится определение, выполняются в фиксированном порядке. Вы можете указать 3 значения, а именно DEFAULT, JVM, NAME_ASCENDING (в алфавитном порядке).

@RunWith

Укажите исполнителя тестов для класса тестов.

Для получения дополнительной информации см.JunitОфициальный сайт:https://junit.org/junit4/

1. Создайте тестовый класс

Далее вы можете создать тестдобрый,Помимо создания вручную тестадобрый,можно использоватьASбыстрая клавиша:Выберите курсор для созданиятестдобрыйиздобрыйпо имени->нажиматьALT + ENTER->существоватьнеожиданно возникнутьиз Выберите во всплывающем окнеCreate Test

Появится следующее всплывающее окно, или щелкните правой кнопкой мыши имя класса и выберите «Перейти» в меню. to–>Test,Также появится следующее всплывающее окно

Отметьте метод, который необходимо протестировать, и автоматически сгенерируется тестовый класс:

Если отмечено@Beforeили@Afterиз Он также автоматически сгенерирует для вас соответствующий ответ.изтестметод

Затем напишите тестовый метод. Сначала напишите несколько бизнес-методов в целевом классе, который будет тестироваться:

Язык кода:javascript
копировать
public class SimpleClass { public boolean isTeenager(int age) { if (age < 15) { return true; } return false; } public int add(int a, int b) { return a + b; } public String getNameById(int id) { if (id == 1) { return «Сяо Мин»; } else if (id == 2){ return «Красненькая»; } return ""; } }

Затем тестовый класс:

Язык кода:javascript
копировать
@RunWith(JUnit4.class) public class SimpleClassTest { private SimpleClass simpleClass; @Before public void setUp() throws Exception { simpleClass = new SimpleClass(); } @After public void tearDown() throws Exception { } @Test public void isTeenager() { Assert.assertFalse(simpleClass.isTeenager(20)); Assert.assertTrue(simpleClass.isTeenager(14)); } @Test public void add() { Assert.assertEquals(simpleClass.add(3, 2), 5); Assert.assertNotEquals(simpleClass.add(3, 2), 4); } @Test public void getNameById() { Assert.assertEquals(simpleClass.getNameById(1), «Сяо Мин»); Assert.assertEquals(simpleClass.getNameById(2), «Красный»); Assert.assertEquals(simpleClass.getNameById(10), ""); } }

вsetUp()да自动генерироватьиздобавить в了@Beforeаннотация,Это будет выполняться перед каждым выполнением тестового метода.,Поэтому существование создает здесь целевой объект,Вы также можете добавить@BeforeClassаннотация Но в это времяsetUp()должен Изменить настатическийизметод。Затемсуществоватькаждыйтестметод Подготовлено втествариант использования,здесьиспользоватьorg.junit.AssertВ сумкеизутверждениеметод,Есть многоassertXXXметод,Вы можете решить, соответствуют ли результаты целевого метода ожиданиям.

2. Общие методы утверждения в классе Assert

метод

значение

assertNull(Object object)

Объект утверждения пуст

assertNull(String message, Object object)

Объект утверждения пусто, если оно не пусто, будет выдано исключение, содержащее указанную информацию о сообщении.

assertNotNull(Object object)

Утвердить, что объект не пуст

assertNotNull(Object object)

Утвердить, что объект не пусто, если оно пусто, будет создано исключение, содержащее указанную информацию о сообщении.

assertSame(Object expected, Object actual)

Утвердить, что два объекта относятся к одному и тому же объекту

assertSame(String message, Object expected, Object actual)

Утвердить, что два объекта относятся к одному и тому же объекту, в противном случае будет выдано исключение с указанной информацией о сообщении.

assertNotSame(Object expected, Object actual)

Утвердить, что два объекта не ссылаются на один и тот же объект.

assertNotSame(String message, Object expected, Object actual)

Утвердить, что два объекта не ссылаются на один и тот же объект.,В противном случае генерируется исключение, содержащее указанную информацию о сообщении.

assertTrue(boolean condition)

Утверждать, что результат верен

assertTrue(String message, boolean condition)

Утверждать, что результат верен, Если значение false, генерируется исключение, содержащее указанную информацию о сообщении.

assertFalse(boolean condition)

Утверждать, что результат неверен

assertFalse(String message, boolean condition)

Утверждать, что результат неверен, Если это правда, генерируется исключение, содержащее указанную информацию о сообщении.

assertEquals(long expected, long actual)

Утверждать, что значения двух длинных типов ожидаемого и фактического равны

assertEquals(String message, long expected, long actual)

Утверждать, что значения двух длинных типов ожидаемого и фактического равным образом, если не равно, будет выброшено исключение, несущее указанную информацию о сообщении.

assertEquals(Object expected, Object actual)

Утверждать, что два объекта равны

assertEquals(String message, Object expected, Object actual)

Утверждать, что два объекта равным образом, если не равно, будет выдано исключение, несущее указанную информацию о сообщении.

assertEquals(float expected, float actual, float delta)

утверждать два float тип expect и actual существовать delta Величина отклонения равна, дельта – погрешность ошибки.

assertEquals(String message, float expected, float actual, float delta)

утверждать два float тип expect и actual существовать delta Значение отклонения равно, если не равно, будет выдано исключение, несущее указанную информацию сообщения.

assertEquals(double expected, double actual, double delta)

утверждать два double тип expect и actual существовать delta Равно ниже значения отклонения

assertEquals(String message, double expected,double actual, double delta)

утверждать два double тип expect и actual существовать delta Значение отклонения равно, если не равно, будет выдано исключение, несущее указанную информацию сообщения.

assertArrayEquals(T[] expected, T[] actual)

утверждать два Элементы одного и того же массива равны во взаимно однозначном соответствии

assertArrayEquals(String message, T[] expected, T[] actual)

утверждать два Элементы одного и того же массива равны во взаимно однозначном соответствии,Если они не равны, будет выдано исключение, несущее указанную информацию о сообщении.

fail()

Просто сделай так, чтобы тест провалился

fail(String message)

Просто сделай так, чтобы тест провалился и выдал сообщение об ошибке

assertThat(T actual, Matcher<? super T> matcher)

Утвердить, что фактические правила сопоставления совпадают

assertThat(String reason, T actual, Matcher<? super T> matcher)

Утвердить, что фактические правила сопоставления совпадают,В противном случае генерируется исключение, содержащее указанную информацию о причине.

вassertEqualsизметод,Каждый соответствует одномуassertNotEqualsметод,Здесь не указано,assertThatда一个强大изметод:

Язык кода:javascript
копировать
 Assert.assertThat(1, is(1)); Assert.assertThat(0, is(not(1))); Assert.assertThat("hello", startsWith("h")); List<String> items = new ArrayList<>(); items.add("aaa"); items.add("bbb"); Assert.assertThat(items, hasItem("aaa"));

Требуется статический импортorg.hamcrest.Matchersдобрыйвизметод,Чтобы узнать больше о методе сопоставления, обратитесь к этому доброму.

3. Запустите тестовый класс

Выберите класс теста, нажмите правой кнопкой мыши «Выполнить», и результаты теста отобразятся на панели управления:

Если все тестовые сценарии нормально возвращают ожидаемые результаты,Тогда перед каждым тестметодом в левой части панели появится зеленая галочка.,в противном случаеметодпревратится в красный восклицательный знак и панель управлениявыходаномальный,Теперь попробуем изменить бизнес-метод:

Язык кода:javascript
копировать
    public boolean isTeenager(int age) { if (age < 15) { return false; } return false; }

Здесь будетage < 15Изменить навыходfalse,Предположим, что это вызвано небрежностью при кодировании.,Затембегать Тестовый класс:

Панель управления сообщит вам, в какой строке ошибка:

Другими словами, здесь не возвращаются ожидаемые результаты, а значит, написанная нами бизнес-логика неверна, и ошибку необходимо исправить.

4. Запустите один метод тестирования или несколько классов тестирования.

Выше весь тестдобрый бег,Если вы хотите запустить один метод тестадобрый,Тогда мышь лишь выбирает для запуска определенный тестовый метод.,Затем щелкните правой кнопкой мыши и выберите «Выполнить». Если вы хотите запустить несколько тестов одновременно,И если в одном пакете имеется несколько тестдобрыйсуществовать,Затем выберите каталог пакета из нескольких тестдобрыйсуществовать.,Затем щелкните правой кнопкой мыши и выберите «Выполнить». В противном случае его можно указать следующим образом,Создать пустой тестдобрый,Затем добавьте аннотации:

Язык кода:javascript
копировать
@RunWith(Suite.class) @Suite.SuiteClasses({SimpleClassTest.class, SimpleClass2Test.class}) public class RunMultiTest { }

Запуск этого тестдоброго запустит указанный тестдобрый вместе с методом.

2. Использование среды тестирования Mockito.

Представленные ранее варианты использования позволяют тестировать только варианты использования кода Java, не задействующие API-интерфейсы, связанные с Android. Это неудобно, если задействованы API-интерфейсы, связанные с Android. В настоящее время, если вы не полагаетесь на сторонние библиотеки, вам могут понадобиться. использовать инструментированное тестирование для запуска на устройствах Android. Run, поэтому есть несколько лучших сторонних альтернативных фреймворков, которые могут имитировать тестирование кода с использованием Android. Mockito — это фреймворк тестирования, основанный на внедрении зависимостей.

1. Понимание концепции Mock

Что такое Мок, Китайское значение этого слова — «имитация» или «ложь», что означает имитация объекта. Зачем подражать? В традиционном модуле тестирования JUnit зависимость от объектов в существованиитеста не устраняется, например, объект A зависит от метода объекта B, с Когда уществоватьтест объекта А, нам необходимо сконструировать объект Б, что увеличивает сложность теста и делает невозможным реализацию какого-либо доброго теста. Это противоречит идее юнит-теста. Другая серьезная проблема заключается в том, что локальный модульный тест не может полагаться на Android API, поскольку он запускает локальную среду JVM. Трудно смоделировать полную среду Android, полагаясь только на чистую тестовую среду JUnit, что приводит к невозможности тестирования Android. связанный код и Mock. Чтобы решить эту проблему, симуляцию объекта можно легко реализовать с помощью Mock.

Добавьте зависимости:

Язык кода:javascript
копировать
dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) testImplementation 'org.mockito:mockito-core:2.19.0' .... }
2. Несколько методов Mock-объектов в Mockito

Перед использованием удобнее импортировать статически:

Язык кода:javascript
копировать
 // Статический импорт делает код чище import static org.mockito.Mockito.*;

Непосредственно издеваться над объектом:

Язык кода:javascript
копировать
    @Test public void testMock() { SimpleClass mockSimple = Mockito.mock(SimpleClass.class); assertNotNull(mockSimple); }

Метод аннотации имитирует объект:

Язык кода:javascript
копировать
    @Mock SimpleClass simple; @Before public void setUp() { MockitoAnnotations.initMocks(this); } @Test public void testMock() { assertNotNull(simple); }

Режим бегуна имитирует объект:

Язык кода:javascript
копировать
@RunWith(MockitoJUnitRunner.class) public class ExampleUnitTest { @Mock SimpleClass simple; @Test public void testMock() { assertNotNull(simple); } } 

Метод MockitoRule имитирует объект:

Язык кода:javascript
копировать
public class ExampleUnitTest { @Mock SimpleClass simple; @Rule //<--использовать@Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); @Test public void testMock() { assertNotNull(simple); } }
3. Поведение при проверке
Использование функции проверки (T Mock)

verify(T mock)из作用дапроверять发生из Некоторые действия эквивалентныverify(mock, times(1)) Например:

Язык кода:javascript
копировать
@Test public void testMock() { //Создаем фиктивный объект List mockedList = mock(List.class); //Используем фиктивный объект mockedList.add("one"); mockedList.clear(); //Проверяем, вызывается ли методockedList.add("one"). Если он вызывается, текущий тест-метод проходит успешно, в противном случае он завершается неудачно. verify(mockedList).add("one"); //проверять Вызывается ли методockedList.clear(), если он вызывается, текущий тест-метод проходит, в противном случае он терпит неудачу. verify(mockedList).clear(); }
Язык кода:javascript
копировать
@Test public void testMock() { mock.someMethod("some arg"); //проверятьmock.someMethod("some arg") вызывается, если он вызывается, тестметод проходит успешно, в противном случае он терпит неудачу. verify(mock).someMethod("some arg"); }

То есть, если вы закомментируете вызывающий метод, запуск метода testMock() завершится неудачей.

проходитьverifyКлючевые слова,После создания макета объекта,Макетный объект запоминает все взаимодействия. Затем вы можете выборочно проверять взаимодействия, которые вас интересуют.

Обычно необходимо сотрудничать с каким-либо тестовым методом для проверки определенного поведения.,Этот метод называется «Заглушки».,Укладка означает выполнение некоторых операций моделирования над имитируемыми объектами.,Например, установка возвращаемого значения моделирования или выдача исключения и т. д.

Распространенный метод укладки:

методимя

методзначение

doReturn(Object toBeReturned)

Задайте значение, которое будет возвращено заранее

doThrow(Throwable… toBeThrown)

Установите исключения, которые будут выброшены заранее

doAnswer(Answer answer)

Перехватите результаты заранее

doCallRealMethod()

Вызвать реальную реализацию определенного метода

doNothing()

Установка функции void ничего не дает

thenReturn(T value)

Установите значение, которое будет возвращено

thenThrow(Throwable… throwables)

Установите исключение, которое будет выброшено

thenAnswer(Answer<?> answer)

Перехватить результаты

Например:

Язык кода:javascript
копировать
 @Test public void testMock() { // Вы можете имитировать определенные функции, а не только интерфейсы. List mockedList = mock(List.class); // Забивка свай when(mockedList.get(0)).thenReturn("first"); doReturn("aaaa").when(mockedList).get(1); when(mockedList.get(1)).thenThrow(new RuntimeException()); doThrow(new RuntimeException()).when(mockedList).clear(); // Вывод «первый» System.out.println(mockedList.get(0)); // Потому что получить(999) Нагромождения нет, поэтому результат равен нулю, Обратите внимание, что в среде моделирования в этом месте не будет сообщаться об исключении IndexOutOfBoundsException. System.out.println(mockedList.get(999)); // Исключение будет выброшено, когда get(1) System.out.println(mockedList.get(1)); // очистить выдаст исключение mockedList.clear(); }

doXXXиthenXXXиспользоватьначальствопочти,Один из них — установить возвращаемое значение перед вызовом метода.,Один из них — установить возвращаемое значение после вызова метода в существующем состоянии. По умолчанию,Все непустые функции макетируемых объектов имеют возвращаемые значения.,Возвращаемое значение по умолчанию для типа объекта равно нулю.,Например возвратint、boolean、Stringизфункция,Возвращаемые значения по умолчанию:0、falseиnull

использоватьwhen(T methodCall)функция

битькучаметод Нужно сотрудничатьwhen(T methodCall)функция,Это значит сделать метод тестовой сваи эффективным. Если вы хотите, чтобы этот макет вызывал определенный метод и возвращал определенное значение,Тогда вы можете использовать его.

Например:

Язык кода:javascript
копировать
when(mock.someMethod()).thenReturn(10); //Вы можете использовать гибкое сопоставление параметров, например when(mock.someMethod(anyString())).thenReturn(10); //Устанавливаем выброшенное исключение when(mock.someMethod("some arg")).thenThrow(new RuntimeException()); //Не могли бы выкдля разных эффектовиз Непрерывные обратные вызовыизметод Забивка свай: //Последняя тестовая стопка (Пример: возвращает объект: «foo») определяет следующий метод обратного вызова и его поведение. when(mock.someMethod("some arg")) .thenReturn("foo")//Сначала вызываем someMethod("some arg") вернет "foo" .thenThrow(new RuntimeException());//Вызов someMethod("some второй раз arg") вызовет исключение //Вы можете использовать следующий метод, чтобы заменить уменьшенную версию связной тестовой стопки: when(mock.someMethod("some arg")) .thenReturn("one", "two"); //и Следующий метод имеет тот же эффект when(mock.someMethod("some arg")) .thenReturn("one") .thenReturn("two"); //Сравниваем меньшую версию связной тестовой стопки и выдаем исключение: when(mock.someMethod("some arg")) .thenThrow(new RuntimeException(), new NullPointerException();
использоватьthenAnswerсделать обратный звоноктесткуча
Язык кода:javascript
копировать
when(mock.someMethod(anyString())).thenAnswer(new Answer() { Object answer(InvocationOnMock invocation) { Object[] args = invocation.getArguments(); Object mock = invocation.getMock(); return "called with arguments: " + args; } }); // выход : "called with arguments: foo" System.out.println(mock.someMethod("foo"));
использоватьdoCallRealMethod()функция Приходитьпозвонитьметодизреальная реализацияметод

Уведомление,существоватьMockсреда,Все объекты моделируются.,Результаты метода также необходимо смоделировать.,Если вы не задали результат симуляции для имитируемого объекта,вернет значение по умолчанию,Например:

Язык кода:javascript
копировать
public class Person { public String getName() { return «Сяо Мин»; } } @Test public void testPerson() { Person mock = mock(Person.class); //выходnull,Если не установлено обратное значение макета, когда(mock.getName()).thenReturn("xxx"); System.out.println(mock.getName() }

Поскольку метод getName() не устанавливает моделируемое возвращаемое значение.,Возвращаемое значение getName() — тип String.,Таким образом, прямой вызов вернет значение String по умолчанию, равное нулю.,Местокначальстволапшакод Если ты хочешьвыходgetName()методизреальная возвращаемая стоимостьизразговаривать,Необходимо установить doCallRealMethod():

Язык кода:javascript
копировать
 @Test public void testPerson() { Person mock = mock(Person.class); doCallRealMethod().when(mock).getName(); //выход“Сяо Мин” System.out.println(mock.getName()); }
использоватьdoNothing()функция предназначена для Установка функции void ничего не дает

нуждаться Уведомлениеизда По умолчанию返回值为voidизфункциясуществоватьmocksсерединада什么也不做из但да,Будут также некоторые особые обстоятельства. нравиться:

Когда тестовая заглушка постоянно вызывает функцию void:

Язык кода:javascript
копировать
   doNothing().doThrow(new RuntimeException()).when(mock).someVoidMethod(); //does nothing the first time: mock.someVoidMethod(); //throws RuntimeException the next time: mock.someVoidMethod();

Отслеживайте реальные объекты, и вы хотите, чтобы функция void ничего не делала:

Язык кода:javascript
копировать
List list = new LinkedList(); List spy = spy(list); //let's make clear() do nothing doNothing().when(spy).clear(); spy.add("one"); //clear() does nothing, so the list still contains "one" spy.clear(); 
использоватьdoAnswer()функцияфункция testvoidизперезвонить

Если вы хотите использовать функцию, которая не возвращает значения,Вы можете использовать функцию doAnswer() с общим параметром добрыйAnswer в качестве теста обратного вызова. Предположим, у вас есть метод void с несколькими параметрами обратного вызова.,Если вы хотите указать обратный вызов для выполнения,Трудно реализовать с помощью thenAnswer,Это будет очень просто, если вы используете doAnswer().,Пример кода выглядит следующим образом:

Язык кода:javascript
копировать
MyCallback callback = mock(MyCallback.class); Mockito.doAnswer(new Answer() { @Override public Object answer(InvocationOnMock invocationOnMock) throws Throwable { //Получаем первый параметр MyCallback call = invocation.getArgument(0); //Указываем обратный вызов для выполнения операции call.onSuccess(); return null; } }).when(mockedObject.requset(callback)); doAnswer(new Answer() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { System.out.println("onSuccess answer"); return null; } }).when(callback).onSuccess(); mockedObject.requset(callback)
Ситуации, когда необходимо использовать функцию doReturn вместо thenReturn

Например, при мониторинге реальных объектов и влиянии вызова реальных функций

Язык кода:javascript
копировать
List list = new LinkedList(); List spy = spy(list); //Невозможно: список все еще пуст, когда вызывается реальный метод, поэтому spy.get(0) выдаст исключение IndexOutOfBoundsException() when(spy.get(0)).thenReturn("foo"); //В это время вам следует использовать функцию doReturn() doReturn("foo").when(spy).get(0);
использоватьdoThrow()функция Приходитьфункция testvoidБросатьаномальный
Язык кода:javascript
копировать
SimpleClass mock = mock(SimpleClass.class); doThrow(new RuntimeException()).when(mock).someVoidMethod(); mock.someVoidMethod();

СуммируяиспользоватьdoThrow(), doAnswer(), doNothing(), doReturn() and doCallRealMethod() Этифункция Когда можноксуществоватьподходящийкогдаиз Звоню на всякий случайwhen()решить некоторые проблемы., Это необходимо, когда вам нужны следующие функции:

  • функция testvoid
  • существуюттест-функция на контролируемом объекте
  • одна и та же функция более одного раза, изменяя поведение фиктивного объекта во время процесса существующего теста.
4. Количество обращений к методу проверки

Нужно использовать какой-то метод

метод

значение

times(int wantedNumberOfInvocations)

Проверьте количество вызовов метода

never()

Убедитесь, что взаимодействие не произошло, что эквивалентно times(0)

only()

Убедитесь, что метод вызывается только один раз.,Эквивалентно раз(1)

atLeast(int minNumberOfInvocations)

Проверьте не менее n раз

atMost(int maxNumberOfInvocations)

Подтверждайте не более n раз

after(long millis)

существуют Подтвердить через заданное время

timeout(long millis)

Проверьте, истекло ли время выполнения метода.

description(String description)

Вывод контента при неудачной проверке

verifyZeroInteractions

Убедитесь, что фиктивный объект не взаимодействует.

Например:

Язык кода:javascript
копировать
mock.someMethod("some arg"); mock.someMethod("some arg"); //проверятьmock.someMethod("some arg") вызывается дважды подряд, то есть, если он не вызывается дважды, проверка не удалась. verify(mock, times(2)).someMethod("some arg");
Язык кода:javascript
копировать
//Уведомление,Следующие три эквивалентны,Все проверяют, что someMethod() вызывается только один раз. someMethod("некоторый аргумент");
Язык кода:javascript
копировать
mPerson.getAge(); mPerson.getAge(); //проверять вызывается минимум 2 раза verify(mPerson, atLeast(2)).getAge(); //проверять можно вызвать не более 2 раз verify(mPerson, atMost(2)).getAge();
Язык кода:javascript
копировать
//Следующие два эквивалентны,Количество вызовов проверки равно 0verify(mPerson, Never()).getAge();verify(mPerson, times(0)).getAge();
Язык кода:javascript
копировать
mPerson.getAge(); mPerson.getAge(); long current = System.currentTimeMillis(); System.out.println(current ); //После задержки в 1 с проверяем, был ли mPerson.getAge() выполнен дважды verify(mPerson, after(1000).times(2)).getAge(); System.out.println(System.currentTimeMillis() - current);
Язык кода:javascript
копировать
 mPerson.getAge(); mPerson.getAge(); //проверятьметодсуществовать вызывался 2 раза до таймаута в 100мс verify(mPerson, timeout(100).times(2)).getAge();
Язык кода:javascript
копировать
  @Test public void testVerifyZeroInteractions() { Person person = mock(Person.class); person.eat("a"); //Поскольку объект person взаимодействует, проверка здесь не удалась. Закомментируйте приведенный выше вызов, и проверка завершится успешно. verifyZeroInteractions(person); //Вы можете убедиться, что несколько объектов не взаимодействуют //verifyZeroInteractions(person,person2 ); }
Язык кода:javascript
копировать
  @Test public void testVerifyZeroInteractions() { Person person = mock(Person.class); person.eat("a"); verify(person).eat("a"); //Обратите внимание, что это не достигнет цели проверки и не может быть смешано сverify(). verifyZeroInteractions(person,person2 ); }
5. Сопоставители параметров (сопоставители)

Mockito проверяет значения параметров в естественном стиле Java: с помощью функцииquals(). Иногда, когда необходима дополнительная гибкость, вы можете использовать средства сопоставления аргументов:

Язык кода:javascript
копировать
// Используйте встроенный Сопоставитель AnyInt(). параметров when(mockedList.get(anyInt())).thenReturn("element"); // Использовать собственный Сопоставитель параметров( Верните свою собственную реализацию сопоставителя в существующей функции isValid(). ) when(mockedList.contains(argThat(isValid()))).thenReturn("element"); // выходelement System.out.println(mockedList.get(999)); // Вы также можете проверить Сопоставитель параметров verify(mockedList).get(anyInt());

Часто используемые средства сопоставления параметров:

методимя

значение

anyObject()

соответствовать любому объекту

any(Class type)

То же, что и любой Объект().

any()

То же, что и любой Объект().

anyBoolean()

Соответствует любому логическому и непустому логическому значению.

anyByte()

Соответствует любому байту и непустому байту

anyCollection()

Соответствует любой непустой коллекции.

anyDouble()

Соответствует любому двойному и непустому двойному значению.

anyFloat()

Соответствует любому веществу с плавающей запятой и непустому значению с плавающей запятой.

anyInt()

Соответствует любому целому непустому целому числу.

anyList()

Сопоставить любой непустой список

anyLong()

Соответствует любому длинному и непустому длинному значению.

anyMap()

Сопоставьте любую непустую карту

anyString()

Соответствует любой непустой строке

contains(String substring)

Параметр содержит данную строку подстроки

argThat(ArgumentMatcher matcher)

Создание шаблонов сопоставления пользовательских параметров

eq(T value)

Параметр соответствия равен определенному значению

Некоторый пример кода:

Язык кода:javascript
копировать
    @Test public void testPersonAny(){ When(mPerson.eat(any(String.class))).thenReturn("рис"); //или: когда(mPerson.eat(anyString())).thenReturn("рис"); //выходрис System.out.println(mPerson.eat("Лапша")); } @Test public void testPersonContains(){ когда(mPerson.eat(contains("мясо"))).thenReturn("мясо"); //выход Лапша System.out.println(mPerson.eat("лицо")); } @Test public void testPersonArgThat(){ //Когда длина пользовательского входного символа является четным числом,выход Лапша。 when(mPerson.eat(argThat(new ArgumentMatcher<String>() { @Override public boolean matches(String argument) { return argument.length() % 2 == 0; } }))).thenReturn("Лапша"); //выход Лапша System.out.println(mPerson.eat("1234")); }

нуждаться Уведомлениеизда,Если вы планируете использовать Сопоставитель параметры, то все параметры должны быть предоставлены сопоставителем. Например:

Язык кода:javascript
копировать
verify(mock).someMethod(anyInt(), anyString(), eq("third argument")); // Приведенный выше код верен, поскольку eq() также является Сопоставителем. параметров verify(mock).someMethod(anyInt(), anyString(), "third argument"); // Приведенный выше код неверен, Поскольку все параметры должны быть предоставлены сопоставителем, а параметр «третий argument"не по Сопоставитель параметры предоставляет, поэтому выдается исключение

Функции сопоставления, такие как Как и любой объект(), eq(), не возвращают совпадения. Они внутренне записывают совпадения в стек.,и возвращает ложное значение,Обычно ноль.

6. Используйте InOrder для проверки порядка выполнения.

Убедитесь, что последовательность выполнения в основномиспользоватьInOrderфункция Например, проверьте последовательность выполнения функции фиктивного объекта:

Язык кода:javascript
копировать
    @Test public void testInorder() { List<String> singleMock = mock(List.class); singleMock.add(«Сяо Мин»); singleMock.add(«Красный»); // Создайте объект inOrder для макетного объекта. InOrder inOrder = inOrder(singleMock); // Убедитесь, что функция добавления сначала выполняет add("Xiao Ming"), а затем add("Xiao Hong"), в противном случае произойдет сбой. inOrder.verify(singleMock).add(«Сяо Мин»); inOrder.verify(singleMock).add(«Красный»); }

Проверьте порядок выполнения функций нескольких макетных объектов:

Язык кода:javascript
копировать
    @Test public void testInorderMulti() { List<String> firstMock = mock(List.class); List<String> secondMock = mock(List.class); firstMock.add(«Сяо Мин»); secondMock.add(«Красный»); // Создайте объекты inOrder для этих двух Mock-объектов. InOrder inOrder = inOrder(firstMock, secondMock); // Проверьте порядок их выполнения inOrder.verify(firstMock).add(«Сяо Мин»); inOrder.verify(secondMock).add(«Красный»); }

Порядок выполнения проверок очень гибкий. Вы можете выбрать один макетный объект или смешать несколько макетных объектов или создать объект InOrder только из тех макетных объектов, которые необходимо проверить по порядку.

7. Используйте Spy для наблюдения за реальными объектами

следить за реальностьюобъектиспользоватьspy()функциягенерировать,или Это также может быть как@Mockтаким образомиспользовать@Spyаннотация Приходитьгенерировать一个мониторобъект,Когда вы создаете шпионский объект для реального объекта,существуют. Когда вы используете этот шпионский объект, реальный объект также будет называться,Если только его функция не заглушена. Используйте шпионские объекты как можно меньше,Вы также должны быть осторожны с формой при ее использовании.

Язык кода:javascript
копировать
    @Test public void testSpy() { List<String> list = new ArrayList<>(); List<String> spy = spy(list); // Вы можете заглушить определенные функции when(spy.size()).thenReturn(100); // Вызов функций на реальных объектах spy.add("one"); spy.add("two"); // выход Первый элемент «единица» System.out.println(spy.get(0)); // Поскольку функция size() является заглушкой, здесь возвращается 100. System.out.println(spy.size()); // Проверить взаимодействие verify(spy).add("one"); verify(spy).add("two"); }

использовать@SpyГенерировать объекты мониторинга:

Язык кода:javascript
копировать
    @Spy
    Person mSpyPerson;

    @Test
    public void testSpyPerson() {
    	//ВыведемPerson Реальная реализация getName() в добром, а не нулевом формате.
        System.out.println(mSpyPerson.getName());
    }

Важно понимать мониторинг реальных объектов! иногда,существоватьмониторобъектначальствоиспользоватьwhen(Object)Приходить进行битькучада不Может能илинереальноиз。поэтому,когдаиспользоватьмониторобъект Пожалуйста, подумайте, когдаdoReturn|Answer|Throw()функцияклан Приходить进行битькуча。Например:

Язык кода:javascript
копировать
List list = new LinkedList(); List spy = spy(list); // невозможно достичь : Поскольку при вызове spy.get(0) будет вызвана функция get(0) реального объекта, // В этот момент возникнет исключение IndexOutOfBoundsException, поскольку реальный объект List пуст. when(spy.get(0)).thenReturn("foo"); // Вам нужно использовать doReturn() для заглушки doReturn("foo").when(spy).get(0);
8. Используйте ArgumentCaptor для захвата параметров

Захват параметров предназначен главным образом для подготовки к следующему этапу утверждения, пример кода:

Язык кода:javascript
копировать
    @Test public void argumentCaptorTest() { List<Object> mock = mock(List.class); mock.add("John"); //Создаем тип параметра для захвата, вот String ArgumentCaptor argument = ArgumentCaptor.forClass(String.class); //Вызов метода аргумента.capture() в параметре существующегоverifyметода для захвата входных параметров verify(mock).add(argument.capture()); //проверить захват параметра "Джон" assertEquals("John", argument.getValue()); }
Язык кода:javascript
копировать
    @Test public void argumentCaptorTest2() { List<Object> mock = mock(List.class); mock.add("Brian"); mock.add("Jim"); ArgumentCaptor argument = ArgumentCaptor.forClass(String.class); verify(mock, times(2)).add(argument.capture()); //Если имеется несколько вызовов параметров, аргумент.getValue() захватывает параметры последнего вызова assertEquals("Jim", argument.getValue()); //Если вы хотите получить все значения параметров, вы можете вызвать аргумент.getAllValues() assertArrayEquals(new Object[]{"Brian","Jim"}, argument.getAllValues().toArray()); }
9. Используйте @InjectMocks для автоматического внедрения зависимых объектов.

Иногда объект, который мы хотим протестировать внутренне, должен зависеть от другого объекта, например:

Язык кода:javascript
копировать
public class User { private Address address; public void setAddress(Address address) { this.address = address; } public String getAddress() { return address.getDetail(); } }
Язык кода:javascript
копировать
public class Address { public String getDetail() { return "detail Address"; } }

Класс User внутренне зависит от класса Address. Когда мы тестируем, нам нужно смоделировать эти два объекта, а затем передать объект Address в User. Это будет довольно сложно, если Mockito будет слишком много зависимых объектов. Предоставилк Нет необходимости вводить вручнуюобъектизметод,первыйиспользовать@InjectMocksаннотациянуждатьсявпрыснутыйизобъект,Например, Пользователь,Затемнуждаться Внедренная зависимостьизобъектиспользовать@Mockили@Spyаннотация,Затем Mockito автоматически завершит процесс инъекции.,Например:

Язык кода:javascript
копировать
    @InjectMocks User mTestUser; @Mock Address mAddress; @Test public void argumentInjectMock() { When(mAddress.getDetail()).thenReturn("Ханчжоу, Чжэцзян"); System.out.println(mTestUser.getAddress()); }

Таким образом, вам не придется беспокоиться о пользователе Установитьадрес ,Просто добавьте аннотации к тому доброму, от которого должен зависеть Пользователь.,Затем сосредоточьтесь непосредственно на написании тестметода.

Или вы можете использовать @Spy для мониторинга внедрения реальных объектов:

Язык кода:javascript
копировать
    @InjectMocks User mTestUser; @Spy Address mAddress; @Test public void argumentInjectMock() { // When(mAddress.getDetail()).thenReturn("Ханчжоу, Чжэцзян"); System.out.println(mTestUser.getAddress()); }

другой:

Еще одна более короткая версия непрерывных звонков:

Язык кода:javascript
копировать
// Первый вызов возвращает «один», второй вызов возвращает «два», а третий вызов возвращает «три». when(mock.someMethod("some arg")).thenReturn("one", "two", "three");

ссылка:Mockito Китайская документация

3. Использование платформы PowerMockito.

Фреймворк Mockito в основном отвечает потребностям, но имеет некоторые ограничения.,Например, static, Final, Private и т. д. нельзя высмеивать.,PowerMockito может решить эти проблемы,PowerMockito — это более мощный фреймворк, расширяющий другие фреймворки, такие как EasyMock. PowerMock использует собственный добрый загрузчик и манипуляции с байт-кодом для имитации статического метода.,Конструктор,finalдобрыйиметод,частныйметод,Удалите статические инициализаторы и т. д.

Добавьте зависимости:

Язык кода:javascript
копировать
    testImplementation 'org.powermock:powermock-module-junit4:2.0.2' testImplementation 'org.powermock:powermock-module-junit4-rule:2.0.2' testImplementation 'org.powermock:powermock-api-mockito2:2.0.2' testImplementation 'org.powermock:powermock-classloading-xstream:2.0.2'
1. Обычный метод Mock

Целевой класс:

Язык кода:javascript
копировать
public class CommonExample { public boolean callArgumentInstance(File file) { return file.exists(); } }

Тестовый класс:

Язык кода:javascript
копировать
public class CommonExamplePowerMockTest { @Test public void testCallArgumentInstance() { File file = PowerMockito.mock(File.class); CommonExample commonExample = new CommonExample(); PowerMockito.when(file.exists()).thenReturn(true); Assert.assertTrue(commonExample.callArgumentInstance(file)); } }

Обычный метод Mock заключается в передаче параметров Mock извне.,По сути, использование только Mockito одно и то же.,Это также можно сделать, используя чистый API Mockito.

2. Новый объект внутри метода Mock.
Язык кода:javascript
копировать
public class CommonExample { public boolean callArgumentInstance(String path) { File file = new File(path); return file.exists(); } }
Язык кода:javascript
копировать
@RunWith(PowerMockRunner.class) @PrepareForTest(CommonExample.class) public class CommonExamplePowerMockTest { @Test public void callCallArgumentInstance2() throws Exception { File file = PowerMockito.mock(File.class); CommonExample commonExample = new CommonExample(); PowerMockito.whenNew(File.class).withArguments("aaa").thenReturn(file); PowerMockito.when(file.exists()).thenReturn(true); Assert.assertTrue(commonExample.callArgumentInstance("aaa")); } }

Единственное отличие от предыдущего состоит в том, что,Здесь объект File создается внутри метода теста.,В это времянуждатьсяпроходитьPowerMockito.whenNew(File.class).withArguments("aaa").thenReturn(file)метод Создание моделированияFileиздействовать,когдаFileдобрыйкaaaиз Создание параметровизпора уже возвращатьсяmockвне Приходитьизfileобъект。同时В это времянуждатьсясуществоватьтестдобрыйначальстводобавить ваннотация@RunWith(PowerMockRunner.class)и@PrepareForTest(CommonExample.class),Обратите внимание, что существованиедобрый добавлен выше,нетсуществоватьметодначальство,Вначале при добавлении существующего метода выдавалось сообщение, что тестметод не найден.,@PrepareForTest()括号вобозначениеизда要тестиз Цельдобрый。

3. Издеваемся над финальным методом обычных объектов
Язык кода:javascript
копировать
public class CommonExample { public boolean callFinalMethod(DependencyClass dependency) { return dependency.isValidate(); } } public class DependencyClass { public final boolean isValidate() { // do something return false; } }
Язык кода:javascript
копировать
@RunWith(PowerMockRunner.class) @PrepareForTest({CommonExample.class, DependencyClass.class}) public class CommonExamplePowerMockTest { @Test public void callFinalMethod() { DependencyClass dependency = PowerMockito.mock(DependencyClass.class); CommonExample commonExample = new CommonExample(); PowerMockito.when(dependency.isValidate()).thenReturn(true); Assert.assertTrue(commonExample.callFinalMethod(dependency)); } }

Точно так же и здесь насмешка должна опираться на объекты доброго характера.,а затем перешел к методу вызова,здесьтакой женуждатьсядобавить в@RunWithи@PrepareForTest,@PrepareForTestМожеткобозначение多个Цельдобрый,Но вот если вам просто нужен тестфинал,Просто добавьте DependencyClass.class.

4. Имитировать статические методы обычных классов
Язык кода:javascript
копировать
public final class Utils { public static String getUUId() { return UUID.randomUUID().toString(); } } public class CommonExample { public String printUUID() { return Utils.getUUId(); } }
Язык кода:javascript
копировать
@RunWith(PowerMockRunner.class) @PrepareForTest(Utils.class) public class StaticUnitTest { @Before public void setUp() throws Exception { PowerMockito.mockStatic(Utils.class); } @Test public void getUUId() { PowerMockito.when(Utils.getUUId()).thenReturn("FAKE UUID"); CommonExample commonExample = new CommonExample(); assertThat(commonExample.printUUID(), is("FAKE UUID")); } }

такой женуждатьсяобозначение@RunWithи@PrepareForTest,@PrepareForTestсередина Укажите статическийметод Местосуществоватьиздобрый,тестстатическийметод ДонуждатьсявызовPowerMockito.mockStatic()метод Приходитьmockстатическийдобрый,Затем Сразупроходитьwhen().thenReturn()метод Укажите статическийметодиз模拟返回值即Может。

5. Проверьте количество вызовов статических методов
Язык кода:javascript
копировать
@Test public void testVerify() { PowerMockito.when(Utils.getUUId()).thenReturn("FAKE UUID"); CommonExample commonExample = new CommonExample(); System.out.println(commonExample.printUUID()); PowerMockito.verifyStatic(Utils.class); Utils.getUUId(); }

статическийметодпроходитьPowerMockito.verifyStatic(Class c)Проверять,Однако разница между этим и Mocktio заключается в том, что вам нужно вызывать статический метод после существования.,в противном случаенет。здесьPowerMockito.verifyStatic(Utils.class)Фактически это эквивалентноPowerMockito.verifyStatic(Utils.class, times(1)),Если вы хотите подтвердить более одного раза,Так:

Язык кода:javascript
копировать
    @Test public void testVerify() { PowerMockito.when(Utils.getUUId()).thenReturn("FAKE UUID"); CommonExample commonExample = new CommonExample(); System.out.println(commonExample.printUUID()); System.out.println(commonExample.printUUID()); PowerMockito.verifyStatic(Utils.class, Mockito.times(2)); Utils.getUUId(); }

На данный момент первый параметр PowerMockito.verifyStatic() указывает класс статического метода.,Второй параметр получает параметр VerificationModeтип.,Таким образом, передача любой функции в Mockito, которая проверяет время метода, будет работать.,Mockitoсерединаизпроверятьфункциявернетсяизда一个VerificationModeтип。такой жесуществоватьPowerMockito.verifyStaticметод后лапша要вызов一次要проверятьизстатическийметод,Здесь всегда странно. . .

6. Используйте реальные возвращаемые значения

Если в процессе существованиятеста вы столкнулись с возвращаемым значением моделирования статического метода, которое не нужно имитировать,,Вместо этого требуется истинное возвращаемое значение.,Что делать,По сути, это то же самое, что и Mockito.,PowerMockitoтакой жепоставлятьthenCallRealMethodилиdoCallRealMethodметод:

Язык кода:javascript
копировать
    @Test public void testRealCall() throws Exception { PowerMockito.when(Utils.getUUId()).thenReturn("FAKE UUID"); //... PowerMockito.when(Utils.getUUId()).thenCallRealMethod(); //Эквивалентно следующему //PowerMockito.doCallRealMethod().when(Utils.class, "getUUId"); System.out.println(Utils.getUUId()); }

Или вы можете напрямую использовать шпион для наблюдения за реальными объектами:

Язык кода:javascript
копировать
    @Test public void testRealCall() { PowerMockito.spy(Utils.class); System.out.println(Utils.getUUId()); }
7. Имитируйте частные методы
Язык кода:javascript
копировать
public class CommonExample { public boolean callPrivateMethod() { return isExist(); } private boolean isExist() { return false; } }
Язык кода:javascript
копировать
@RunWith(PowerMockRunner.class) @PrepareForTest(CommonExample.class) public class PrivateUnitTest { @Test public void testCallPrivateMethod() throws Exception { CommonExample commonExample = PowerMockito.mock(CommonExample.class); PowerMockito.when(commonExample.callPrivateMethod()).thenCallRealMethod(); PowerMockito.when(commonExample, "isExist").thenReturn(true); Assert.assertTrue(commonExample.callPrivateMethod()); } }

Использование существования мало чем отличается от чистого Mockito, за исключением того, что частный метод Mock реализуется через следующий API:

Язык кода:javascript
копировать
PowerMockito.when(Object instance, String methodName, Object... arguments)

существуют при работе в PowerMockito по сравнению с Mockito,Самое большое изменение заключается в том, что появилось больше перегрузок методаName, которые передают Stringтипметод.,Таким образом, существование можно использовать практически во всем.

8. Имитируйте частные переменные обычных классов
Язык кода:javascript
копировать
public class CommonExample { private static final int STATE_NOT_READY = 0; private static final int STATE_READY = 1; private int mState = STATE_NOT_READY; public boolean doSomethingIfStateReady() { if (mState == STATE_READY) { // DO some thing return true; } else { return false; } } }
Язык кода:javascript
копировать
    @Test public void testDoSomethingIfStateReady() throws Exception { CommonExample sample = new CommonExample(); Whitebox.setInternalState(sample, "mState", 1); assertThat(sample.doSomethingIfStateReady(), is(true)); }

проходитьWhitebox.setInternalStateПриходить Изменятьчастныйпеременные-члены,В данном случае нетнуждатьсяобозначение@RunWithи@PrepareForTest

9. Имитация статических методов void
Язык кода:javascript
копировать
public class CommonExample { public static void doSomething(String a) { System.out.println("doSomething"+a); } }
Язык кода:javascript
копировать
@RunWith(PowerMockRunner.class) @PrepareForTest({CommonExample.class}) public class StaticUnitTest { @Test public void testStaticVoid() throws Exception { PowerMockito.mockStatic(CommonExample.class); PowerMockito.doNothing().when(CommonExample.class, "doSomething", Mockito.any()); CommonExample.doSomething("aaa"); } }

По умолчаниюпроходитьPowerMockito.mockStaticизстатическийдобрыйизvoidизметодда什么也不做из,Однако doNothing можно выполнить явно. Закомментирование строки doNothing в приведенном выше коде ничего не даст. Что, если вы хотите что-то сделать вместо doNothing?,То же, что Мокито,использоватьdoAnswer:

Язык кода:javascript
копировать
    @Test public void testStaticVoid() throws Exception { PowerMockito.mockStatic(CommonExample.class); PowerMockito.doAnswer(new Answer<Object>() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { System.out.println(invocation.getArguments()[0]); return null; } }).when(CommonExample.class, "doSomething", Mockito.any()); CommonExample.doSomething("aaa"); }
10. Финальный статический класс Mock-системы.
Язык кода:javascript
копировать
public class CommonExample { public int callSystemStaticMethod(int a, int b) { return Math.max(a, a+b); } }
Язык кода:javascript
копировать
@RunWith(PowerMockRunner.class) @PrepareForTest(CommonExample.class) public class StaticUnitTest { @Test public void callSystemStaticMethod() { CommonExample commonExample = new CommonExample(); PowerMockito.mockStatic(Math.class); PowerMockito.when(Math.max(anyInt(), anyInt())).thenReturn(100); Assert.assertEquals(100, commonExample.callSystemStaticMethod(10, -5)); } }

@PrepareForTestДобавить систему звонков вдобрый Местосуществоватьиздобрый,Здесь следует отметить, что если вы используете PowerMockito для издевательства над системой, статический финалдобрый,Тогда вы больше не сможете добавлять простые библиотеки зависимостей Mockito к своим зависимостям gradle.,В противном случае издевательство здесь не удастся.,подскажетMockito can not mock/spy final class, Поскольку сам PowerMockito уже имеет поддержку библиотеки зависимостей для Mockito, вы можете полагаться только на PowerMockito. За исключением ситуации, когда система является статически окончательной, в других случаях на PowerMockito и Mockito можно положиться одновременно (я тестирую без проблем). Кроме того, новая версия простого Mockito также поддерживает final добрый final методиз Макет, но добавлять файлы конфигурации неудобно.

4. Использование системы тестирования Robolectric.

Поскольку часть Робоэлектрика относительно длинная,,Месток单独放了一篇文章середина:Изучение и использование фреймворка модульного тестирования Android Robolectric

5. Использование среды тестирования Espresso.

Espresso — это тестовая среда для тестирования инструментов Android.,Это библиотека, официально продвигаемая Google. Поскольку содержание части «Эспрессо» также относительно длинное.,Месток单独放了一篇文章середина:Использование фреймворка Espressotest

Издатель: Лидер стека программистов полного стека, укажите источник для перепечатки: https://javaforall.cn/155001.html Исходная ссылка: https://javaforall.cn

boy illustration
Углубленный анализ переполнения памяти CUDA: OutOfMemoryError: CUDA не хватает памяти. Попыталась выделить 3,21 Ги Б (GPU 0; всего 8,00 Ги Б).
boy illustration
[Решено] ошибка установки conda. Среда решения: не удалось выполнить первоначальное зависание. Повторная попытка с помощью файла (графическое руководство).
boy illustration
Прочитайте нейросетевую модель Трансформера в одной статье
boy illustration
.ART Теплые зимние предложения уже открыты
boy illustration
Сравнительная таблица описания кодов ошибок Amap
boy illustration
Уведомление о последних правилах Points Mall в декабре 2022 года.
boy illustration
Даже новички могут быстро приступить к работе с легким сервером приложений.
boy illustration
Взгляд на RSAC 2024|Защита конфиденциальности в эпоху больших моделей
boy illustration
Вы используете ИИ каждый день и до сих пор не знаете, как ИИ дает обратную связь? Одна статья для понимания реализации в коде Python общих функций потерь генеративных моделей + анализ принципов расчета.
boy illustration
Используйте (внутренний) почтовый ящик для образовательных учреждений, чтобы использовать Microsoft Family Bucket (1T дискового пространства на одном диске и версию Office 365 для образовательных учреждений)
boy illustration
Руководство по началу работы с оперативным проектом (7) Практическое сочетание оперативного письма — оперативного письма на основе интеллектуальной системы вопросов и ответов службы поддержки клиентов
boy illustration
[docker] Версия сервера «Чтение 3» — создайте свою собственную программу чтения веб-текста
boy illustration
Обзор Cloud-init и этапы создания в рамках PVE
boy illustration
Корпоративные пользователи используют пакет регистрационных ресурсов для регистрации ICP для веб-сайта и активации оплаты WeChat H5 (с кодом платежного узла версии API V3)
boy illustration
Подробное объяснение таких показателей производительности с высоким уровнем параллелизма, как QPS, TPS, RT и пропускная способность.
boy illustration
Удачи в конкурсе Python Essay Challenge, станьте первым, кто испытает новую функцию сообщества [Запускать блоки кода онлайн] и выиграйте множество изысканных подарков!
boy illustration
[Техническая посадка травы] Кровавая рвота и отделка позволяют вам необычным образом ощипывать гусиные перья! Не распространяйте информацию! ! !
boy illustration
[Официальное ограниченное по времени мероприятие] Сейчас ноябрь, напишите и получите приз
boy illustration
Прочтите это в одной статье: Учебник для няни по созданию сервера Huanshou Parlu на базе CVM-сервера.
boy illustration
Cloud Native | Что такое CRD (настраиваемые определения ресурсов) в K8s?
boy illustration
Как использовать Cloudflare CDN для настройки узла (CF самостоятельно выбирает IP) Гонконг, Китай/Азия узел/сводка и рекомендации внутреннего высокоскоростного IP-сегмента
boy illustration
Дополнительные правила вознаграждения амбассадоров акции в марте 2023 г.
boy illustration
Можно ли открыть частный сервер Phantom Beast Palu одним щелчком мыши? Супер простой урок для начинающих! (Прилагается метод обновления сервера)
boy illustration
[Играйте с Phantom Beast Palu] Обновите игровой сервер Phantom Beast Pallu одним щелчком мыши
boy illustration
Maotouhu делится: последний доступный внутри страны адрес склада исходного образа Docker 2024 года (обновлено 1 декабря)
boy illustration
Кодирование Base64 в MultipartFile
boy illustration
5 точек расширения SpringBoot, супер практично!
boy illustration
Глубокое понимание сопоставления индексов Elasticsearch.
boy illustration
15 рекомендуемых платформ разработки с нулевым кодом корпоративного уровня. Всегда найдется та, которая вам понравится.
boy illustration
Аннотация EasyExcel позволяет экспортировать с сохранением двух десятичных знаков.