Тестирование Cognito Authentication в приложении iOS
У меня есть приложение для iOS с аутентификацией Cognito, реализованной очень похоже на CognitoYourUserPoolsSample. Самые важные фрагменты находятся в SignInViewController.swift:
Когда пользователь нажимает Войти, добавляется асинхронная задача:
var passwordAuthenticationCompletion: AWSTaskCompletionSource<AWSCognitoIdentityPasswordAuthenticationDetails>? ... @IBAction func signInPressed<...> { ... let authDetails = AWSCognitoIdentityPasswordAuthenticationDetails(username: self.username.text!, password: self.password.text! ) self.passwordAuthenticationCompletion?.set(result: authDetails) ...
Позже мы получим либо успех, либо ответ об ошибке:
extension SignInViewController: AWSCognitoIdentityPasswordAuthentication { public func getDetails<...> { DispatchQueue.main.async { // do something in case of success ... public func didCompleteStepWithError<...> { DispatchQueue.main.async { // do something in case of failure ...
У меня также есть тест пользовательского интерфейса, который заполняет имя пользователя и пароль, нажимает Вход и проверяет ответ:
class MyAppUITests: XCTestCase {
...
func loginTest() {
let usernameField = <...>
usernameField.tap()
usernameField.typeText("user@domain.com")
...
// same for password field
// then click Sign In
<...>.buttons["Sign In"].tap()
В настоящее время этот тест работает против реальной инфраструктуры AWS, которая не идеальна по многим причинам. Вместо этого я хочу смоделировать различные ответы от AWS.
Как я могу это сделать?
Я думаю, что лучше всего было бы посмеяться над очередью заданий, но я не знаю, как к этому подойти. Любое направление будет высоко ценится. Если вы справились с подобной задачей альтернативным способом, я бы тоже хотел услышать ваши идеи, спасибо.
1 ответ
Ладно, я не очень знаком с AWS iOS SDK и с тем, как именно он реализует поток аутентификации, поэтому возьмем следующее с небольшим количеством соли. Это не полный ответ, а более общая "стратегия", я надеюсь. Я реализовал аналогичный подход в моем текущем проекте, не только для входа в систему, но фактически для всех удаленных подключений, которые я делаю.
Есть три вещи, которые вам нужно сделать:
Запустите небольшой локальный веб-сервер внутри вашей цели тестирования пользовательского интерфейса. Я использую Посольство и Посол для этого в моем текущем проекте. Настройте его так, чтобы он возвращал любой ответ, который обычно дает Cognito (или другая конечная точка). Я просто
curl
отредактировал запрос вручную и где-то сохранил ответ, но в моем случае я получил простые данные (а не, например, полную страницу входа для просмотра в веб-просмотре...). Я предполагаю, что Cognito на самом деле показывает вид входа в систему (веб) и при успешном входе в систему использует глубокую ссылку, чтобы "вернуться" к вашему приложению, которое в конечном итоге вызывает вашAWSCognitoIdentityPasswordAuthentication
методы (успех или ошибка). У вас может быть цель теста, то есть веб-сервер вызывает прямую ссылку напрямую, если вы знаете, как она выглядит (что должно быть возможно узнать?).Добавьте некоторый механизм для переключения конечной точки Cognito во время теста. К сожалению, это требует добавления производственного кода, но если все сделано правильно, это не должно быть слишком сложным. Я сделал это с помощью переменной среды запуска, которую я установил во время теста (см. Ниже). Если ваш веб-сервер не поддерживает https (Embassy не из коробки), это также требует некоторой настройки App Transport Security. Самым сложным является, конечно, выяснить, где в SDK создана эта конечная точка и как ее изменить. Беглый взгляд на документацию заставляет меня поверить, что
webDomain
где он сохранен, но я не вижу, как он настроен. Это свойство доступно только для чтения, что усложняет ситуацию. Я предполагаю, однако, что вы можете изменить это в какой-то конфигурации в вашем проекте? Иначе это пахнет как случай для метода метания... Извините, я не могу предложить больше звукового направления здесь.Во время ваших тестов убедитесь, что реальные конечные точки, к которым будет осуществляться доступ во время соответствующих потоков приложений, переключены на
http://localhost/...
, Я сделал это с помощьюXCUIApplication().launchEnvironment["somekey"] = "TESTINGKEY"
, что соответствовало моей подготовке производственного кода на втором этапе. В моем случае я мог просто загрузить разные конечные точки (у которых был домен localhost и в остальном те же пути, что и у исходных доменов). Настройте ответы вашего веб-сервера в соответствии с тестовым примером (успешный вход в систему, неверные учетные данные и т. Д.).
Я признаю, что это было / очень много работы, но для меня это стоило того, так как я мог легко запустить весь поток приложений (который включал много исходящих запросов) без какого-либо доступа к сети. В любом случае я должен был реализовать нашу систему аутентификации самостоятельно, что давало мне большой контроль над тем, какие URL-адреса использовались и где, облегчая создание единого места для их удаления в зависимости от переменной среды запуска. Самой уродливой частью в моем случае было включение исключений ATS только в моих тестах, для чего мне пришлось использовать скрипт запуска по разным причинам.