Waitforexpectationswithtimeout
Obter através da App Store Leia esta publicação em nosso aplicativo!
XCTestCase # waitFalseExpectationUntilTimeout implementação.
Estou trabalhando em um projeto iOS e eu estou no comando de testar a maioria das partes dele. À medida que eu escrevo alguns testes, muitas vezes eu tenho a necessidade de aguardar um método assíncrono para finalizar e, em seguida, teste que algo não aconteceu.
Por exemplo, tente iniciar sessão com um nome de usuário e senha inválidos, aguarde até que as comunicações de rede sejam finalizadas e, em seguida, teste que o usuário não conseguiu fazer o login.
Swift tem alguns métodos astutos para testar esse tipo de coisas; os que eu mais uso são expectationForPredicate e waitForExpectationsWithTimeout. Esses métodos são bons para testar que algo aconteceu depois que o método assíncrono termina. No entanto, para testar que algo não aconteceu (o que eu quero), não parece haver nada projetado especificamente para isso.
Não consigo usar predicados, porque isso fará com que o teste expire cedo. Eu não consigo modificar o código que está sendo testado porque é um retorno de retorno do ciclo de vida do aplicativo e nós testadores geralmente não modificamos nenhum código, nós apenas testamos.
É por isso que projetei esse método.
A principal coisa que a função faz é agendar um cronômetro e atender a todas as expectativas logo antes do período de espera. O método TimeTimeout expira. Essa é a melhor maneira de lidar com essa situação? O que posso melhorar com este método (além de comentar)? Quaisquer problemas de concorrência que eu deveria estar preocupado?
Para adicionar algum contexto, waitForExpectationsWithTimeout fará com que o teste falhe se não forem cumpridas as expectativas antes do tempo limite, e é por isso que eu tinha que cumprir todas as expectativas logo antes de esse tempo limite ocorrer.
Esta é uma solução extremamente complicada para um problema relativamente simples.
O método waitForExpectationsWithTimeout deve ser usado apenas para garantir que uma expectativa assíncrona específica foi atendida.
Então, no caso em que estamos testando se o usuário foi ou não logado com sucesso, seria tentador escrever algo ao longo das linhas de:
Mas, problemática, esse teste pode falhar por dois motivos:
O usuário não efetuou login com sucesso. A expectativa não foi atendida no limite de tempo.
Se o teste falhar, não podemos ter certeza se ele teria passado com um limite de tempo maior ou se retornou muito rapidamente, mas não foi bem-sucedido.
Então, precisamos modificar nosso teste para se parecer mais com isso:
Agora, o teste determina se o código assíncrono foi ou não executado e, em caso afirmativo, verificamos se o login foi ou não um sucesso (ou o que a variável de sucesso representa aqui).
Agora, você está procurando o caso oposto. Você não quer saber se o usuário efetuou login ou não, mas se o usuário foi ou não impedido de efetuar login. E isso é tão simples quanto inverter um XCTAssertTrue para um XCTAssertFalse.
É importante notar que esse padrão não requer nenhum código complicado (é claro que deveríamos escrever testes em torno de nós mesmos). Nossos testes estão usando coisas exclusivamente da caixa do Xcode Test Suite - exatamente o que qualquer um que olha para nossa base de código esperaria ver. É muito direto o que está acontecendo aqui.
E somos capazes de distinguir entre o retorno da chamada assíncrona ou se isso aconteceu, mas obtivemos um resultado ruim. Há uma grande diferença aqui entre um teste falhando porque o código assíncrono não foi executado antes do nosso tempo e ele correu, mas deu um resultado incorreto. Precisamos distinguir claramente entre esses resultados e, para isso, não é necessário escrever nenhum código complicado.
Uma observação importante aqui é certificar-se de que cumprir a expectativa é a última coisa que você faz nos retornos de chamada assíncronos, ou você pode configurar uma condição de corrida.
E, finalmente, seus testes certamente devem ser muito mais robustos do que isso. Por fim, devemos testar com respostas de rede ridicularizadas e devemos saber, para cada teste, exatamente qual resposta de rede obteremos. Devemos testar que, qualquer que seja o código que esteja fazendo, o login retorna as informações corretas para nós. Há uma diferença entre o servidor permitindo que o usuário faça logon com sucesso e negue o usuário com credenciais inválidas. Há também uma diferença entre credenciais inválidas e obter qualquer número de vários erros do servidor (mais comumente, erros no intervalo 5xx). Obter um 503 e obter uma resposta de credencial inválida está longe da mesma coisa, e seus testes devem validar você está recebendo o que você espera obter.
Então, basicamente, acabei de lhe dizer que esqueça completamente todo o código que você escreveu. E vou ficar de acordo com isso. Não há nenhum motivo para o código que você escreveu para existir. Mas ainda podemos falar sobre alguns dos problemas que seu código existente tem.
Esse nome de função tem um nome estranho: waitFalseExpectationsUntilTimeout. É difícil para mim contar pelo nome sozinho o que esperar que esse método faça. Ele é semelhante ao método waitForExpectationsWithTimeout (timeout: NSTimeInterval, handler: XCWaitCompletionHandler?) Existente, mas ele tem essa matriz estranha de expectativas nas quais eu deveria passar. O nome precisa ser melhor. Algo como AssertUnfulFilledExpectationsWithTimeout.
Mesmo com o melhor nome, estamos aqui em problemas extraordinários. Tanto quanto posso ver, não há meios públicos para verificar se a expectativa já foi ou não cumprida anteriormente. Seu código realmente não faz nada além do cumprimento de todas as expectativas no último momento antes do teste ser concluído. Não assegura que não foram cumpridas anteriormente.
Esta variável merece um nome melhor, e essa lógica quer merecer um comentário ou deve ser completamente eliminada. Eu optaria por eliminá-lo completamente e atirar uma exceção se o usuário tiver passado um valor inferior a 0,5. E, finalmente, essa lógica é, em última análise, problemática, porque você pode acabar com tempo negativo (se o tempo limite for inferior a 0,5).
Você provavelmente deve optar por alguma lógica que se parece mais com isso:
Finalmente, há vários problemas com a classe aninhada:
Primeiro, não precisamos marcar isso como uma função objc. Podemos, em vez disso, marcá-lo como dinâmico.
Em segundo lugar, estamos lançando forças, mas não somos Jedi. Isso não passaria o meu conjunto pessoal de regras de swiftlint, onde force-casting é considerado um erro e se recusa a compilar.
Em terceiro lugar, expc é um nome de variável sem sentido, e não há valor real para abreviar aqui.
Em quarto lugar, você cumpriu com erros ortográficos, embora tenha sido escrito corretamente várias outras vezes neste contexto em virtude de nomes de métodos de preenchimento automático.
Em quinto lugar, por que não adicionamos apenas um método à extensão para lidar com isso em vez de complicar com uma classe aninhada com um nome estranho?
Então, essa é uma versão significativamente mais limpa e segura do seu código. mas, novamente, não afirmaram que essas expectativas não foram cumpridas antes de você as cumprir (tanto quanto eu sei que é impossível). E, em última análise, é um grande número de códigos para implementar, testar, manter e verificar se funciona. e isso é especialmente assim, quando comparamos isso com a simples expectativa + asserção combo que esbocei no topo desta resposta.
Eu queria adicionar um adendo no caso de o problema ser que existe um determinado bloco de código que só é executado no caso de um login bem-sucedido. Se este é o cenário, existem apenas duas possibilidades.
A primeira é que existem blocos separados de sucesso e falha. Algo nesse sentido:
Neste caso, a essência é aproximadamente a mesma que eu descrevi no topo. Queremos cumprir a expectativa em ambos os blocos, mas no bloco de sucesso, vamos apenas adicionar um XCTFail ("Usuário foi permitido fazer o login") para que ainda possamos esperar por este bloco (ou o bloco de falha) para executar, mas se tomar esse caminho, falhamos pelo motivo específico em que o ramo errado foi inserido (em vez de simplesmente pegar o caminho certo, mas não levá-lo rápido o suficiente).
O outro caso é que existe apenas um retorno de chamada para o caminho de sucesso:
Se ESTE é o design, não tenho a menor idéia de como seu aplicativo consegue dar qualquer comentário ao usuário, de modo que algo deu errado durante o processo de login. Eu sei que você não pode modificar o código, mas você precisa estar dizendo às pessoas que podem precisar para solucionar esse problema.
Waitforexpectationswithtimeout
Obter através da App Store Leia esta publicação em nosso aplicativo!
waitForExpectationsWithTimeout falha.
Estou tentando testar um pedido assíncrono com XCTest e, portanto, usando expectationWithDescription :. No entanto, quando waitForExpectationsWithTimeout é chamado, ele imediatamente trava mesmo sem esperar o tempo limite. Eu até tentei colocar a operação de conclusão logo após apenas para excluir um problema de tempo limite, mas isso não muda as coisas; Esta é a minha função:
O mesmo comportamento acontece em outras funções. Se eu tirar a operação waitForExpectationsWithTimeout e manter a operação expectationWithDescription, ela falha no final da função. Em ambos os casos, o crash repot é o seguinte:
Você pode tentar fornecer a implementação para o manipulador. Como o parâmetro do manipulador de documentos não é opcional na marcação waitForExpectationsWithTimeout:
Portanto, você pode tentar fornecer um manipulador descompactado explicitamente (mesmo um vazio irá fazer o trabalho):
Além disso, você pode tentar seguir este post e ver se você obtém log de falhas mais apropriado.
Eu assisti a conversa específica na WWDC14 e saiu com a seguinte implementação:
é muito semelhante ao original, mas para a posição do comando waitForExpectationsWithTimeout, que parece ser crucial.
Teste assíncrono.
O teste assíncrono foi feito muito mais fácil com a introdução das expectativas ea classe XCTestExpectation. Além do suporte básico de expectativa, incluem métodos auxiliares para testar KVO, Notificações e usar Predicados. As expectativas são criadas por métodos auxiliares no XCTestCase.
Principios básicos da expectativa.
Esta é a expectativa básica, você chama de preenchimento () nela.
Você precisa esperar que as expectativas sejam cumpridas por qualquer processo assíncrono que você está testando. Como o nome indica que ele aguardará todas as expectativas que você criou no teste. Eu geralmente só tenho um.
Expectativas complexas.
Eu escrevi o código de teste para uma NSNotification uma vez - sugada e foi uma perda de tempo. Existem alguns bons métodos de fábrica de expectativa, desde que cobrem alguns casos complicados que você definitivamente deve pensar em usar primeiro, não só faz seu teste mais enxuto, mas está escrito para você.
Expectativas do KVO.
Se o teste de conformidade com o KVO definitivamente usar uma expectativa de KVO. Mesmo se não testar explicitamente o KVO, considere se seu teste está interagindo com um objeto compatível com o KVO. HopeValue pode ser nulo para esperar que o valor mude para qualquer outro valor. As expectativas com manipuladores opcionais serão preenchidas se não forem fornecidas. Se você usar seu próprio retorno de manipulador para cumprir a expectativa.
Expectativas de notificação.
Espere uma NSNotification em uma linha. Se você não especificar um manipulador, ele será preenchido pela primeira notificação correspondente do objeto especificado, caso contrário, o manipulador deve retornar verdadeiro para atender a expectativa.
Expectativas predicadas.
Durante o teste, o NSPredicate será avaliado periodicamente. Uma vez que é verdade, a expectativa será cumprida, a menos que você especifique um manipulador, caso em que seu manipulador também deve retornar.
É isso para as expectativas padrão. Gostaria que houvesse uma expectativa de delegado na biblioteca padrão, que iria amarrar as coisas bem e ter os testes assíncronos mais comuns cobertos. Eu tenho uma rápida implementação de um aqui, mas um incluído no XCTest seria ótimo.
Isso foi originalmente postado em Ashton-W.
Ao bater palmas mais ou menos, você pode nos indicar quais são as histórias que realmente se destacam.
Teste assíncrono com Xcode 6.
Em 2013, a Apple enviou uma estrutura de teste renovada no Xcode chamada XCTest, e houve muita alegria. A estrutura antiga não tinha sido atualizada há anos, e várias ferramentas e frameworks de teste de terceiros surgiram para fornecer novos recursos e recursos. Foi bom ver as ferramentas incorporadas recebendo algum amor novamente, e este ano, a Apple está enviando alguns recursos com o Xcode 6 que faltavam na atualização do ano passado. Um que particularmente me agrada ver é o suporte para testes assíncronos.
Se tivermos um teste que tenha que iniciar uma tarefa assíncrona, seja executado em outro tópico ou no runloop do thread principal, como podemos testá-lo?
Considere uma solicitação na web. Poderíamos lançar uma solicitação da web e passar um bloco de conclusão e fazer nossas asserções de teste no manipulador de conclusão ou não. No entanto, como o pedido na Web ainda não foi feito, muito menos uma resposta recebida nem o nosso bloqueio de conclusão foi chamado, nosso método de teste vai sair antes que as afirmações sejam testadas.
Vamos olhar para um teste para uma classe que baixa páginas da web. Normalmente, não queremos fazer solicitações reais da web nos testes. Em vez disso, nós superamos os pedidos usando alguma ferramenta (eu sou parcial para OHHTTPStubs). Mas para os propósitos desses exemplos, iremos quebrar algumas regras e fazer pedidos reais da web.
Podemos dar à classe em teste um URL e bloco de manipulação de conclusão, e irá baixar a página e chamar o bloco, passando por uma seqüência de caracteres contendo a página da web ou uma string vazia se ocorrer uma falha. Não é uma ótima API, mas, novamente, estamos quebrando algumas regras. No entanto, o código de teste abaixo nunca irá falhar. O método de teste retornará sem dar a conclusão do bloqueio de Handler uma chance de ser chamado.
Antes da versão do XCTest do Xcode 6, usando apenas o que vem na lata com o Xcode, nós poderíamos sentar e girar em um loop while que chama o loop de execução da thread principal até que a resposta chegue ou algum período de timeout tenha decorrido. Aqui está o código de teste de trabalho, o antigo caminho.
O loop while executa o loop de execução do thread principal por 10 milissegundos de cada vez até que a resposta chegue, ou até que 5 segundos decorram sem que ele tenha chegado. Isso é útil. Não é terrível. Não é o fim do mundo do desenvolvimento de software ", mas não é ótimo.
Agora, é uma maneira melhor.
Altas expectativas.
Com o Xcode 6, a Apple adicionou expectativas de teste ao framework XCTest na forma da classe XCTestExpectation. Quando criamos uma expectativa de teste, a estrutura de teste espera que ela seja cumprida em algum momento no futuro. Nosso código de teste cumpre a expectativa no bloco de conclusão com uma chamada para o método XCTestExpectation. Isso substitui a configuração de uma flag como responseHasArrived no exemplo anterior. Em seguida, contamos que o framework de teste espera (com um tempo limite) para que suas expectativas sejam cumpridas através do método XCTestCase waitForExpectationsWithTimeout: handler:. Se o manipulador de conclusão for executado dentro do tempo limite e o atendimento de chamadas, todas as expectativas do teste terão sido atendidas. Caso contrário, o teste terá uma existência triste, solitária e não cumprida, até que saia do escopo. E vivendo uma existência triste, solitária e insatisfeita, quero dizer que a expectativa falha no teste após o tempo limite.
A expectativa fracassada não deve ser tão desanimada. Lembre-se de que um resultado falido não é o sinal de um teste ruim; um resultado indeterminado é. Essa expectativa pode sentir orgulho ao declarar o fracasso.
Aqui é um exemplo usando XCTestExpectation:
Crie a expectativa com uma descrição para tornar os resultados mais legíveis. No bloco de conclusão, chame [expectativa preenchida] para dizer o teste que esta expectativa, de fato, foi cumprida. Então, saia no waitForExpectationsWithTimeout: manipulador: até que a solicitação seja enviada, a resposta chega e o nosso manipulador de conclusão é chamado ou o tempo limite ocorre.
Isso é bom, objetivo-C, mas também podemos fazê-lo na nova e brilhante linguagem swift da Apple.
E isso é isso. É uma classe fácil de usar para testar o código assíncrono.
Não é possível obter informações suficientes sobre o iOS 8 e o Swift? Junte-se a nós para o início do iOS com Swift e Advanced iOS bootcamps.
Cursos Big Nerd Ranch iOS.
Interessado em aprender mais sobre nossos cursos básicos e avançados de iOS?
Aprenda com os especialistas em um Bootcamp Big Nerd Ranch!
Screencasts Big Nerd Ranch.
Interessado em nivelar suas habilidades de codificação dos mesmos autores do Big Nerd Ranch Guide? Assine a The Frontier hoje!
Posts Relacionados:
Charles Brian Quinn.
Comentários recentes.
Desenvolvimento de aplicativos.
Treinamento em equipe.
Empresa.
Direitos autorais e cópia; 1998 - 2018 Big Nerd Ranch, LLC. Todos os direitos reservados. | Política de Privacidade.
Teste da unidade iOS.
É sobre TDD, teste de unidade e criação de código livre de insetos no iOS.
Testes unitários assíncronos usando XCTestExpectation.
Me deparei com um post interessante de Phil Beauvoir sobre Teste de Unidade Assíncrona no Xcode 6 usando o novo XCTestExpectation. Ele explica como ele converteu os testes de unidade iOS assíncronos Objective-C existentes para Swift, ao mesmo tempo que os tornou mais eficientes e legíveis usando uma instância de XCTestExpectation e waitForExpectationsWithTimeout ().
O XCTestExpectation é uma classe simples com 1 método: fulfill (). Crie uma instância e conecte o preenchimento () quando a expectativa foi atendida.
Em sua seção de declaração de teste, chame waitForExpectationsWithTimeout (), passando pelo XCTestExpectation, e Voila! Testes unitários assíncronos.
Ao contrário de usar um loop de giro, isso informa explicitamente ao framework XCTest que seu teste está aguardando que um evento assíncrono aconteça, permitindo que ele realize outros testes enquanto espera.
Pós-navegação.
Um pensamento sobre & ldquo; Testes unitários assíncronos usando XCTestExpectation & rdquo;
I & # 8217; começaram a usar as expectativas um pouco. Eles são realmente bons porque me permitem remover algumas classes de suporte de teste cheias de funcionalidades semelhantes para lidar com código assíncrono. Definitivamente vale o esforço para aplicar.
Deixe uma resposta Cancelar resposta.
Você precisa estar logado para postar um comentário.
A Mutual Mobile está contratando.
Estamos à procura de engenheiros de iOS seniores realmente bons em Austin e Hyderabad.
Livros recomendados.
Divulgação completa: recebo uma pequena taxa de referência se você comprar qualquer um dos livros acima usando esses links.
O que eu estou lendo / fazendo agora.
Programação moderna de C ++ com desenvolvimento test-driven.
Programação DSP.
Programação orientada por protocolo.
Livros Safari Online.
Vídeos recomendados.
Este é o meu vídeo de teste de unidade lynda. Foi feito no Xcode 4, então está um pouco datado neste momento. Certifique-se de verificar todos os outros excelentes vídeos de desenvolvedores na lynda também.
Há vídeos da WWDC no teste da unidade do iOS, por exemplo, Teste no Xcode 6.
Para uma introdução à programação iOS, veja o meu último curso lynda "Up and running with iOS SDK".
Podcasts recomendados.
Minha entrevista no NSBrief sobre testes de unidades. Realizado em dezembro passado, eu já aprendi coisas novas e respondia a algumas perguntas de maneira diferente agora.
aguarde Expectativas com tempo limite: manipulador:
Aguarda até que todas as expectativas sejam atendidas ou o tempo limite seja atingido.
Declaração.
Parâmetros.
A quantidade de tempo em que todas as expectativas devem ser atendidas.
Um bloqueio opcional XCWait Completion Handler para invocar quando todas as expectativas foram cumpridas ou quando o tempo limite de espera é disparado. (O tempo limite é sempre tratado como uma falha de teste).
Discussão.
Este método cria um ponto de sincronização no fluxo de um teste. Apenas uma espera Por Expectativas Com Tempo Limite: manipulador: pode estar ativo a qualquer momento, mas várias sequências discretas de "criam expectativas e esperam que elas sejam atendidas". podem ser encadeados.
Este método aguarda as expectativas criadas apenas com os métodos de conveniência da XCTest Case & # x27 ;. Este método não espera as expectativas criadas manualmente por meio de inicializações no XCTest Expectation ou suas subclasses.
Para aguardar as expectativas criadas manualmente, use a opção esperar por expectativas: tempo limite: ou espere por expectativas: tempo limite: impor ordem: métodos ou os métodos correspondentes no XCTWaiter, passando uma lista explícita de expectativas.
Os clientes não devem manipular o loop de execução ao usar esta API.
À espera de expectativas.
Espera em um grupo de expectativas até o tempo limite especificado.
Espera uma série de expectativas e especifica se elas devem ser cumpridas na ordem dada.
Um bloco a ser chamado quando uma chamada para aguardar For Expectations With Timeout: manipulador: todas as expectativas foram cumpridas, ou expirou.
Códigos de erro para erros que podem ocorrer enquanto espera que as expectativas sejam cumpridas.
Domínio de erro para erros que podem ocorrer enquanto espera que as expectativas sejam cumpridas.
Obter através da App Store Leia esta publicação em nosso aplicativo!
waitForExpectationsWithTimeout falha.
Estou tentando testar um pedido assíncrono com XCTest e, portanto, usando expectationWithDescription :. No entanto, quando waitForExpectationsWithTimeout é chamado, ele imediatamente trava mesmo sem esperar o tempo limite. Eu até tentei colocar a operação de conclusão logo após apenas para excluir um problema de tempo limite, mas isso não muda as coisas; Esta é a minha função:
O mesmo comportamento acontece em outras funções. Se eu tirar a operação waitForExpectationsWithTimeout e manter a operação expectationWithDescription, ela falha no final da função. Em ambos os casos, o crash repot é o seguinte:
Você pode tentar fornecer a implementação para o manipulador. Como o parâmetro do manipulador de documentos não é opcional na marcação waitForExpectationsWithTimeout:
Portanto, você pode tentar fornecer um manipulador descompactado explicitamente (mesmo um vazio irá fazer o trabalho):
Além disso, você pode tentar seguir este post e ver se você obtém log de falhas mais apropriado.
Eu assisti a conversa específica na WWDC14 e saiu com a seguinte implementação:
é muito semelhante ao original, mas para a posição do comando waitForExpectationsWithTimeout, que parece ser crucial.
Teste assíncrono.
O teste assíncrono foi feito muito mais fácil com a introdução das expectativas ea classe XCTestExpectation. Além do suporte básico de expectativa, incluem métodos auxiliares para testar KVO, Notificações e usar Predicados. As expectativas são criadas por métodos auxiliares no XCTestCase.
Principios básicos da expectativa.
Esta é a expectativa básica, você chama de preenchimento () nela.
Você precisa esperar que as expectativas sejam cumpridas por qualquer processo assíncrono que você está testando. Como o nome indica que ele aguardará todas as expectativas que você criou no teste. Eu geralmente só tenho um.
Expectativas complexas.
Eu escrevi o código de teste para uma NSNotification uma vez - sugada e foi uma perda de tempo. Existem alguns bons métodos de fábrica de expectativa, desde que cobrem alguns casos complicados que você definitivamente deve pensar em usar primeiro, não só faz seu teste mais enxuto, mas está escrito para você.
Expectativas do KVO.
Se o teste de conformidade com o KVO definitivamente usar uma expectativa de KVO. Mesmo se não testar explicitamente o KVO, considere se seu teste está interagindo com um objeto compatível com o KVO. HopeValue pode ser nulo para esperar que o valor mude para qualquer outro valor. As expectativas com manipuladores opcionais serão preenchidas se não forem fornecidas. Se você usar seu próprio retorno de manipulador para cumprir a expectativa.
Expectativas de notificação.
Espere uma NSNotification em uma linha. Se você não especificar um manipulador, ele será preenchido pela primeira notificação correspondente do objeto especificado, caso contrário, o manipulador deve retornar verdadeiro para atender a expectativa.
Expectativas predicadas.
Durante o teste, o NSPredicate será avaliado periodicamente. Uma vez que é verdade, a expectativa será cumprida, a menos que você especifique um manipulador, caso em que seu manipulador também deve retornar.
É isso para as expectativas padrão. Gostaria que houvesse uma expectativa de delegado na biblioteca padrão, que iria amarrar as coisas bem e ter os testes assíncronos mais comuns cobertos. Eu tenho uma rápida implementação de um aqui, mas um incluído no XCTest seria ótimo.
Isso foi originalmente postado em Ashton-W.
Ao bater palmas mais ou menos, você pode nos indicar quais são as histórias que realmente se destacam.
Teste assíncrono com Xcode 6.
Em 2013, a Apple enviou uma estrutura de teste renovada no Xcode chamada XCTest, e houve muita alegria. A estrutura antiga não tinha sido atualizada há anos, e várias ferramentas e frameworks de teste de terceiros surgiram para fornecer novos recursos e recursos. Foi bom ver as ferramentas incorporadas recebendo algum amor novamente, e este ano, a Apple está enviando alguns recursos com o Xcode 6 que faltavam na atualização do ano passado. Um que particularmente me agrada ver é o suporte para testes assíncronos.
Se tivermos um teste que tenha que iniciar uma tarefa assíncrona, seja executado em outro tópico ou no runloop do thread principal, como podemos testá-lo?
Considere uma solicitação na web. Poderíamos lançar uma solicitação da web e passar um bloco de conclusão e fazer nossas asserções de teste no manipulador de conclusão ou não. No entanto, como o pedido na Web ainda não foi feito, muito menos uma resposta recebida nem o nosso bloqueio de conclusão foi chamado, nosso método de teste vai sair antes que as afirmações sejam testadas.
Vamos olhar para um teste para uma classe que baixa páginas da web. Normalmente, não queremos fazer solicitações reais da web nos testes. Em vez disso, nós superamos os pedidos usando alguma ferramenta (eu sou parcial para OHHTTPStubs). Mas para os propósitos desses exemplos, iremos quebrar algumas regras e fazer pedidos reais da web.
Podemos dar à classe em teste um URL e bloco de manipulação de conclusão, e irá baixar a página e chamar o bloco, passando por uma seqüência de caracteres contendo a página da web ou uma string vazia se ocorrer uma falha. Não é uma ótima API, mas, novamente, estamos quebrando algumas regras. No entanto, o código de teste abaixo nunca irá falhar. O método de teste retornará sem dar a conclusão do bloqueio de Handler uma chance de ser chamado.
Antes da versão do XCTest do Xcode 6, usando apenas o que vem na lata com o Xcode, nós poderíamos sentar e girar em um loop while que chama o loop de execução da thread principal até que a resposta chegue ou algum período de timeout tenha decorrido. Aqui está o código de teste de trabalho, o antigo caminho.
O loop while executa o loop de execução do thread principal por 10 milissegundos de cada vez até que a resposta chegue, ou até que 5 segundos decorram sem que ele tenha chegado. Isso é útil. Não é terrível. Não é o fim do mundo do desenvolvimento de software ", mas não é ótimo.
Agora, é uma maneira melhor.
Altas expectativas.
Com o Xcode 6, a Apple adicionou expectativas de teste ao framework XCTest na forma da classe XCTestExpectation. Quando criamos uma expectativa de teste, a estrutura de teste espera que ela seja cumprida em algum momento no futuro. Nosso código de teste cumpre a expectativa no bloco de conclusão com uma chamada para o método XCTestExpectation. Isso substitui a configuração de uma flag como responseHasArrived no exemplo anterior. Em seguida, contamos que o framework de teste espera (com um tempo limite) para que suas expectativas sejam cumpridas através do método XCTestCase waitForExpectationsWithTimeout: handler:. Se o manipulador de conclusão for executado dentro do tempo limite e o atendimento de chamadas, todas as expectativas do teste terão sido atendidas. Caso contrário, o teste terá uma existência triste, solitária e não cumprida, até que saia do escopo. E vivendo uma existência triste, solitária e insatisfeita, quero dizer que a expectativa falha no teste após o tempo limite.
A expectativa fracassada não deve ser tão desanimada. Lembre-se de que um resultado falido não é o sinal de um teste ruim; um resultado indeterminado é. Essa expectativa pode sentir orgulho ao declarar o fracasso.
Aqui é um exemplo usando XCTestExpectation:
Crie a expectativa com uma descrição para tornar os resultados mais legíveis. No bloco de conclusão, chame [expectativa preenchida] para dizer o teste que esta expectativa, de fato, foi cumprida. Então, saia no waitForExpectationsWithTimeout: manipulador: até que a solicitação seja enviada, a resposta chega e o nosso manipulador de conclusão é chamado ou o tempo limite ocorre.
Isso é bom, objetivo-C, mas também podemos fazê-lo na nova e brilhante linguagem swift da Apple.
E isso é isso. É uma classe fácil de usar para testar o código assíncrono.
Não é possível obter informações suficientes sobre o iOS 8 e o Swift? Junte-se a nós para o início do iOS com Swift e Advanced iOS bootcamps.
Cursos Big Nerd Ranch iOS.
Interessado em aprender mais sobre nossos cursos básicos e avançados de iOS?
Aprenda com os especialistas em um Bootcamp Big Nerd Ranch!
Screencasts Big Nerd Ranch.
Interessado em nivelar suas habilidades de codificação dos mesmos autores do Big Nerd Ranch Guide? Assine a The Frontier hoje!
Posts Relacionados:
Charles Brian Quinn.
Comentários recentes.
Desenvolvimento de aplicativos.
Treinamento em equipe.
Empresa.
Direitos autorais e cópia; 1998 - 2018 Big Nerd Ranch, LLC. Todos os direitos reservados. | Política de Privacidade.
Teste da unidade iOS.
É sobre TDD, teste de unidade e criação de código livre de insetos no iOS.
Testes unitários assíncronos usando XCTestExpectation.
Me deparei com um post interessante de Phil Beauvoir sobre Teste de Unidade Assíncrona no Xcode 6 usando o novo XCTestExpectation. Ele explica como ele converteu os testes de unidade iOS assíncronos Objective-C existentes para Swift, ao mesmo tempo que os tornou mais eficientes e legíveis usando uma instância de XCTestExpectation e waitForExpectationsWithTimeout ().
O XCTestExpectation é uma classe simples com 1 método: fulfill (). Crie uma instância e conecte o preenchimento () quando a expectativa foi atendida.
Em sua seção de declaração de teste, chame waitForExpectationsWithTimeout (), passando pelo XCTestExpectation, e Voila! Testes unitários assíncronos.
Ao contrário de usar um loop de giro, isso informa explicitamente ao framework XCTest que seu teste está aguardando que um evento assíncrono aconteça, permitindo que ele realize outros testes enquanto espera.
Pós-navegação.
Um pensamento sobre & ldquo; Testes unitários assíncronos usando XCTestExpectation & rdquo;
I & # 8217; começaram a usar as expectativas um pouco. Eles são realmente bons porque me permitem remover algumas classes de suporte de teste cheias de funcionalidades semelhantes para lidar com código assíncrono. Definitivamente vale o esforço para aplicar.
Deixe uma resposta Cancelar resposta.
Você precisa estar logado para postar um comentário.
A Mutual Mobile está contratando.
Estamos à procura de engenheiros de iOS seniores realmente bons em Austin e Hyderabad.
Livros recomendados.
Divulgação completa: recebo uma pequena taxa de referência se você comprar qualquer um dos livros acima usando esses links.
O que eu estou lendo / fazendo agora.
Programação moderna de C ++ com desenvolvimento test-driven.
Programação DSP.
Programação orientada por protocolo.
Livros Safari Online.
Vídeos recomendados.
Este é o meu vídeo de teste de unidade lynda. Foi feito no Xcode 4, então está um pouco datado neste momento. Certifique-se de verificar todos os outros excelentes vídeos de desenvolvedores na lynda também.
Há vídeos da WWDC no teste da unidade do iOS, por exemplo, Teste no Xcode 6.
Para uma introdução à programação iOS, veja o meu último curso lynda "Up and running with iOS SDK".
Podcasts recomendados.
Minha entrevista no NSBrief sobre testes de unidades. Realizado em dezembro passado, eu já aprendi coisas novas e respondia a algumas perguntas de maneira diferente agora.
aguarde Expectativas com tempo limite: manipulador:
Aguarda até que todas as expectativas sejam atendidas ou o tempo limite seja atingido.
Declaração.
Parâmetros.
A quantidade de tempo em que todas as expectativas devem ser atendidas.
Um bloqueio opcional XCWait Completion Handler para invocar quando todas as expectativas foram cumpridas ou quando o tempo limite de espera é disparado. (O tempo limite é sempre tratado como uma falha de teste).
Discussão.
Este método cria um ponto de sincronização no fluxo de um teste. Apenas uma espera Por Expectativas Com Tempo Limite: manipulador: pode estar ativo a qualquer momento, mas várias sequências discretas de "criam expectativas e esperam que elas sejam atendidas". podem ser encadeados.
Este método aguarda as expectativas criadas apenas com os métodos de conveniência da XCTest Case & # x27 ;. Este método não espera as expectativas criadas manualmente por meio de inicializações no XCTest Expectation ou suas subclasses.
Para aguardar as expectativas criadas manualmente, use a opção esperar por expectativas: tempo limite: ou espere por expectativas: tempo limite: impor ordem: métodos ou os métodos correspondentes no XCTWaiter, passando uma lista explícita de expectativas.
Os clientes não devem manipular o loop de execução ao usar esta API.
À espera de expectativas.
Espera em um grupo de expectativas até o tempo limite especificado.
Espera uma série de expectativas e especifica se elas devem ser cumpridas na ordem dada.
Um bloco a ser chamado quando uma chamada para aguardar For Expectations With Timeout: manipulador: todas as expectativas foram cumpridas, ou expirou.
Códigos de erro para erros que podem ocorrer enquanto espera que as expectativas sejam cumpridas.
Domínio de erro para erros que podem ocorrer enquanto espera que as expectativas sejam cumpridas.
No comments:
Post a Comment