Introdução ao Python (27) Teste (2)

1. Aula de teste

Escrevemos um teste para uma única função anteriormente, vamos escrever um teste para uma classe. As classes são usadas em muitos programas, por isso é útil provar que nossas classes funcionam corretamente. Se os testes da classe forem aprovados, podemos ter certeza de que as melhorias feitas na classe não quebraram acidentalmente seu comportamento original.

2. Vários métodos de afirmação

O Python fornece muitos métodos de asserção na classe unittest.TestCase. Como mencionado anteriormente, o método de asserção verifica se uma condição que você acha que deveria ser verdadeira é realmente verdadeira. Se a condição for realmente atendida, sua suposição sobre o comportamento do programa é confirmada e você pode ter certeza de que não há erros nele. O Python gerará uma exceção se uma condição que você acha que deveria ser verdadeira não for verdadeira.

A Tabela 11-1 descreve seis métodos de asserção comumente usados. Use esses métodos para verificar se o valor retornado é igual ou diferente do valor esperado, se o valor retornado é True ou False e se o valor retornado está na lista ou não. Esses métodos só podem ser usados ​​em classes que herdam unittest.TestCase, então veja como usar um deles ao testar uma classe.

insira a descrição da imagem aqui

3. Uma classe para testar

O teste de classe é semelhante ao teste de função, pois a maior parte do que você faz é testar o comportamento dos métodos na classe. No entanto, ainda existem algumas diferenças. Vamos escrever uma classe para testar. Vejamos uma classe que ajuda a gerenciar enquetes anônimas:

  class AnonymousSurvey:
      """收集匿名调查问卷的答案。"""def __init__(self, question):
          """存储一个问题,并为存储答案做准备。"""
          self.question = question
          self.responses = []def show_question(self):
          """显示调查问卷。"""
          print(self.question)def store_response(self, new_response):
          """存储单份调查答卷。"""
          self.responses.append(new_response)def show_results(self):
          """显示收集到的所有答卷。"""
          print("Survey results:")
          for response in self.responses:
              print(f"- {
      
      response}")

Esta classe primeiro armazena uma pergunta de pesquisa (consulte ❶) e cria uma lista vazia para armazenar as respostas. Esta classe contém métodos para imprimir perguntas de pesquisa (consulte ❷), métodos para adicionar novas respostas à lista de respostas (consulte ❸) e métodos para imprimir todas as respostas armazenadas na lista (consulte ❹). Para criar uma instância dessa classe, basta fornecer uma pergunta. Assim que tivermos uma instância representando uma pesquisa, podemos usar show_question() para exibir as perguntas nela, store_response() para armazenar as respostas e show_results() para exibir os resultados da pesquisa.

Para demonstrar que a classe AnonymousSurvey funciona corretamente, escreva um programa que a utilize:

from survey import AnonymousSurvey

# 定义一个问题,并创建一个调查。
question = "What language did you first learn to speak?"
my_survey = AnonymousSurvey(question)

# 显示问题并存储答案。
my_survey.show_question()
print("Enter 'q' at any time to quit.\n")
while True:
    response = input("Language: ")
    if response == 'q':
        break
    my_survey.store_response(response)

# 显示调查结果。
print("\nThank you to everyone who participated in the survey!")
my_survey.show_results()

Esse programa define uma pergunta ("Qual idioma você aprendeu a falar?") e cria um objeto AnonymousSurvey usando essa pergunta. Em seguida, o programa chama show_question() para exibir a pergunta e solicitar uma resposta ao usuário. Armazene cada resposta à medida que for recebida. Depois que o usuário inserir todas as respostas (digite q para sair), chame show_results() para imprimir os resultados da pesquisa:

What language did you first learn to speak?
Enter 'q' at any time to quit.

Language: English
Language: Spanish
Language: English
Language: Mandarin
Language: q

Thank you to everyone who participated in the survey!
Survey results:
- English
- Spanish
- English
- Mandarin

A classe AnonymousSurvey pode ser usada para realizar pesquisas anônimas simples. Suponha que o colocamos no módulo de pesquisa e queremos melhorá-lo: permitir que cada usuário insira várias respostas; escreva um método que liste apenas as diferentes respostas e indique quantas vezes cada resposta aparece; escreva outra classe para gerenciar pesquisas não anônimas.

Há riscos em fazer as modificações acima e podem afetar o comportamento atual da classe AnonymousSurvey. Por exemplo, permitir várias respostas por usuário pode modificar inadvertidamente como as respostas individuais são tratadas. Para garantir que nenhum comportamento existente seja interrompido ao desenvolver este módulo, escreva testes nesta classe.

4. Teste a classe AnonymousSurvey

Vamos escrever um teste que verifica um aspecto do comportamento da classe AnonymousSurvey: Se o usuário fornecer apenas uma resposta a uma pergunta de pesquisa, essa resposta será armazenada adequadamente. Para isso, usaremos o método assertIn() para verificar se esta resposta realmente está na lista de respostas depois de armazenada:

  import unittest
  from survey import AnonymousSurvey

❶ class TestAnonymousSurvey(unittest.TestCase):
      """针对AnonymousSurvey类的测试。"""def test_store_single_response(self):
          """测试单个答案会被妥善地存储。"""
          question = "What language did you first learn to speak?"
❸         my_survey = AnonymousSurvey(question)
          my_survey.store_response('English')
❹         self.assertIn('English', my_survey.responses)

  if __name__ == '__main__':
      unittest.main()

Primeiro importe o módulo unittest e a classe AnonymousSurvey a ser testada. Nomeie o caso de teste como TestAnonymousSurvey, que também herda unittest.TestCase (consulte ❶). O primeiro método de teste valida: Depois que uma única resposta a uma pergunta da pesquisa é armazenada, ela é incluída na lista de resultados da pesquisa. Um bom nome descritivo para este método é test_store_single_response() (veja ❷). Se esse teste falhar, podemos dizer pelo nome do método na saída que há um problema ao armazenar respostas individuais da pesquisa.

Para testar o comportamento de uma classe, uma instância dela precisa ser criada. Em ❸, crie uma instância chamada my_survey com a pergunta "Qual idioma você aprendeu a falar?", e então use o método store_response() para armazenar a única resposta Inglês. Em seguida, verifique se o inglês está contido na lista my_survey.responses para verificar se a resposta foi armazenada corretamente (consulte ❹).

Os testes passam quando executamos test_survey.py:

.
----------------------------------------------------------------------
Ran 1 test in 0.001s

OK

Tudo bem, mas uma pesquisa que coleta apenas uma resposta não é muito útil. Vamos verificar que quando o usuário fornece três respostas, elas também são armazenadas corretamente. Para fazer isso, adicione mais um método ao TestAnonymousSurvey:

  import unittest
  from survey import AnonymousSurvey

  class TestAnonymousSurvey(unittest.TestCase):
      """针对AnonymousSurvey类的测试。"""

      def test_store_single_response(self):
          --snip--

      def test_store_three_responses(self):
          """测试三个答案会被妥善地存储。"""
          question = "What language did you first learn to speak?"
          my_survey = AnonymousSurvey(question)
❶         responses = ['English', 'Spanish', 'Mandarin']
          for response in responses:
              my_survey.store_response(response)for response in responses:
              self.assertIn(response, my_survey.responses)

  if __name__ == '__main__':
      unittest.main()

Nomeamos o método test_store_three_responses() e criamos um objeto de pesquisa dentro dele, como fizemos para test_store_single_response(). Defina uma lista de três respostas diferentes (consulte ❶) e chame store_response() em cada uma delas. Depois de armazenar essas respostas, use um loop para verificar se cada resposta está incluída em my_survey.responses (consulte ❷).

Quando test_survey.py é executado novamente, ambos os testes (um para uma única resposta e outro para três respostas) passam:

..
----------------------------------------------------------------------
Ran 2 tests in 0.000s

OK

A abordagem anterior funciona bem, mas os testes são um tanto repetitivos. Vamos usar outro recurso do unittest para melhorar sua eficiência.

5. Método setUp()

No test_survey.py anterior, criamos uma instância de AnonymousSurvey em cada método de teste e criamos as respostas em cada método. A classe unittest.TestCase contém um método setUp() que nos permite criar esses objetos uma vez e usá-los em cada método de teste. Se o método setUp() estiver incluído na classe TestCase, o Python o executará primeiro e, em seguida, executará cada método começando com test_. Dessa forma, o objeto criado no método setUp() pode ser usado em todos os métodos de teste que você escrever.

O seguinte usa setUp() para criar um objeto de pesquisa e um conjunto de respostas para uso pelos métodos test_store_single_response() e test_store_three_responses():

  import unittest
  from survey import AnonymousSurvey

  class TestAnonymousSurvey(unittest.TestCase):
      """针对AnonymousSurvey类的测试。"""

      def setUp(self):
          """
          创建一个调查对象和一组答案,供使用的测试方法使用。
          """
          question = "What language did you first learn to speak?"
❶         self.my_survey = AnonymousSurvey(question)
❷         self.responses = ['English', 'Spanish', 'Mandarin']

      def test_store_single_response(self):
          """测试单个答案会被妥善地存储。"""
          self.my_survey.store_response(self.responses[0])
          self.assertIn(self.responses[0], self.my_survey.responses)

      def test_store_three_responses(self):
          """测试三个答案会被妥善地存储。"""
          for response in self.responses:
              self.my_survey.store_response(response)
          for response in self.responses:
              self.assertIn(response, self.my_survey.responses)

  if __name__ == '__main__':
      unittest.main()

O método setUp() faz duas coisas: cria um objeto de pesquisa (consulte ❶) e cria uma lista de respostas (consulte ❷). Os nomes das variáveis ​​que armazenam essas duas coisas incluem o prefixo self (ou seja, armazenado em atributos) e, portanto, podem ser usados ​​em qualquer lugar dessa classe. Isso torna os dois métodos de teste mais simples, pois não precisam criar objetos de pesquisa e respostas. O método test_store_single_response() verifica se a primeira resposta self.responses[0] em self.responses está armazenada corretamente, e o método test_store_three_response() verifica se todas as três respostas em self.responses estão armazenadas corretamente.

Ambos os testes também passam quando test_survey.py é executado novamente. Esses testes são úteis se você deseja estender o AnonymousSurvey para permitir que cada usuário insira várias respostas. Depois de modificar o código para aceitar várias respostas, execute esses testes para confirmar que o comportamento de armazenar uma única resposta ou um intervalo de respostas não é afetado.

Ao testar uma classe que você escreve, o método setUp() torna mais fácil escrever métodos de teste: você pode criar uma série de instâncias e definir suas propriedades no método setUp() e, em seguida, usar essas instâncias diretamente no método de teste. Isso é muito mais fácil do que criar uma instância e definir suas propriedades em cada método de teste.

Acho que você gosta

Origin blog.csdn.net/qq_41600018/article/details/131333417
Recomendado
Clasificación