Как протестировать REST API, использующий Retrofit и Dagger2

Я хотел бы создать модульный тест, который проверяет, что API успешно получает список репозиториев. Я хотел бы, чтобы тест действительно выполнял сетевое соединение, а не использовал Mock Server. Кроме того, было бы неплохо использовать, например, RoboElectric, чтобы тест можно было запустить на JVM.

Это для тестирования модели из архитектуры MVP.

Я использую образец проекта от Mosby, он использует Dagger 2 и Retrofit 1.9.

public interface GithubApi
{
    @GET("/repositories")
    @Headers("Cache-Control: no-cache")
    public void getRepos(Callback<List<Repo>> callback);
}

Это модуль:

@Module()
public class SampleModule
{
    @Provides @Singleton public GithubApi providesGithubApi()
    {
        OkHttpClient client = new OkHttpClient();
        client.setCache(new Cache(context.getCacheDir(), 10 * 1024 * 1024));

        RestAdapter restAdapter = new RestAdapter.Builder()
            .setClient(new OkClient(client))
            .setEndpoint("https://api.github.com")
            .build();

        return restAdapter.create(GithubApi.class);
    }
}

person Kenenisa Bekele    schedule 25.01.2016    source источник


Ответы (2)


Что вы на самом деле хотите протестировать? Я спрашиваю, потому что кажется, что вы не понимаете, чего на самом деле хотите:

  • Тестируете API? Задача серверной части — предоставить полностью работающий API.
  • Проверяете, правильно ли ваше приложение выполняет HTTP-связь? Это звучит так, что вы хотите протестировать Retrofit. Но Retrofit уже протестирован. Вы можете считать, что модернизация работает, и вам не нужно тестировать ее снова.
  • Проверка правильности анализа json? Это уже есть у jackson или gson, который используется внутри Retrofit. Опять же, нет необходимости проверять это снова.

Итак, все тот же вопрос: что вы на самом деле хотите протестировать на «Модели» (уровень бизнес-логики в MVP)? Если модернизация - это вся ваша бизнес-логика, то можно протестировать следующие вещи (еще не протестированные внешними библиотеками, как упоминалось выше):

  • Правильно ли аннотированы ваши классы POJO, чтобы gson/jackson правильно десериализовал json, полученный от Github API. Как это сделать? В этом случае вам нужны надежные фиктивные данные и вы не можете использовать живой API. В этом случае вы должны издеваться над ответом сервера. В противном случае вы не сможете написать модульный тест, потому что GithubApi вернет другие данные, если вы снова запустите свой тест завтра.
  • Вы можете проверить, правильно ли вы обрабатываете все коды ответов http в своем приложении. Однако вам также необходимо имитировать Github API, иначе вы не сможете имитировать, что Github API возвращает ответ 404 или 401 и т. д.

Итак, это тип модульных тестов, которые вы можете написать для модульного тестирования «модели», если ваша модель просто модифицирована.

Я хотел бы, чтобы тест действительно выполнял сетевое соединение, а не использовал Mock Server.

Надеюсь, теперь вы понимаете, что MockServer нужен.

В противном случае может показаться, что вы хотите написать что-то вроде интеграционного теста. Но опять же, что вы на самом деле хотите проверить с помощью этого интеграционного теста?

Мне кажется, что вы просто хотите убедиться, что ваше приложение не падает при загрузке данных из GithubAPI и прокрутке списка элементов в вашем пользовательском интерфейсе, верно?

Так что такие «интеграционные тесты» можно писать как с Robolectric, так и с Espresso. Но на самом деле это не тест! есть ли у вас assertEquals() и т. д. в таком тесте? Так что это довольно глупый тест, потому что вы не можете ничего проверить, кроме того, что ваше приложение не падает. Если это то, что вы ищете, продолжайте, напишите тест Espresso для своей активности, который загружает данные в реальном времени и прокручивает ваш recylcerview до конца. Но на самом деле вы почти ничего не охватили таким тестом. Это ненадежно, воспроизводимо и только проверяет, что ваше приложение не падает на «счастливом пути». Но это почти то же самое, что делать это вручную при запуске приложения.

Поэтому спросите себя: что я хочу проверить? Что на самом деле я должен проверить? Как уже было сказано, тестирование модернизации не имеет смысла, потому что она уже проверена квадратом. Тестирование того, что прокрутка RecyclerView работает, также не имеет смысла, потому что виджет пользовательского интерфейса RecyclerView уже протестирован внутри платформы Android.

person sockeqwe    schedule 26.01.2016
comment
Привет, у меня пара вопросов по первому пункту. - Это работа бэкенда по предоставлению работающего API, но как мы определяем работающий API? он может работать правильно, но принимать другие аргументы, чем вчера. - Если я являюсь бэкэнд-разработчиком и решу изменить параметры и/или структуру json в ответе, когда приложение сможет это обнаружить и на каком уровне тестов? - Если я имитирую сервер, как мне получить уведомление, когда мои фиктивные данные больше не актуальны? - person Tornike Kikalishvili; 12.02.2021

Ключевое слово, которое вы ищете, — интеграционный тест. Интеграционные тесты всегда сложны (поскольку вы полагаетесь на подключение к Интернету, тесты могут быть ненадежными), и я бы посоветовал вам поработать над этим после того, как вы закончите все модульные тесты и тесты пользовательского интерфейса. Вот две ссылки, которые могут быть вам полезны:

person iamkaan    schedule 25.01.2016