Qual é a diferença entre setUp () e setUpClass () em unittest Python?

99

Qual é a diferença entre setUp()e setUpClass()na unittestestrutura Python ? Por que a configuração seria tratada em um método e não no outro?

Quero entender que parte da configuração é feita nas funções setUp()e setUpClass(), bem como com tearDown()e tearDownClass().

Etja
fonte

Respostas:

147

A diferença se manifesta quando você tem mais de um método de teste em sua classe. setUpClasse tearDownClasssão executados uma vez para toda a classe; setUpe tearDownsão executados antes e depois de cada método de teste.

Por exemplo:

class Example(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        print("setUpClass")

    def setUp(self):
        print("setUp")

    def test1(self):
        print("test1")

    def test2(self):
        print("test2")

    def tearDown(self):
        print("tearDown")

    @classmethod
    def tearDownClass(cls):
        print("tearDownClass")

Quando você executa este teste, ele imprime:

setUpClass
setUp
test1
tearDown
.setUp
test2
tearDown
.tearDownClass

(Os pontos ( .) são unittesta saída padrão quando um teste passa.) Observe que setUpe tearDownaparecem antes e depois de test1 e test2 , enquanto setUpClasse tearDownClassaparecem apenas uma vez, no início e no final de todo o caso de teste.

Benjamin Hodgson
fonte
A ordem não deveria ser essa? : setUpClass setUp test1 tearDown .setUp test2 .tearDown tearDownClass
Jai Sharma
Observe o "." na frente de tearDown e a ausência de "." na frente do tearDownClass
Jai Sharma
Ah, desculpe, não percebi isso. Não, unittestnão considera um teste aprovado até que tearDownseja concluído sem incidentes.
Benjamin Hodgson
Portanto, cada um dos métodos test1 e test2 deve ter seu próprio conjunto de setUp e tearDown, certo? Em sua resposta, test1 não tem nenhum método tearDown e, portanto, deveria ter impresso a saída padrão (com.). Corrija-me se eu estiver errado.
Jai Sharma de
1
A saída da resposta está correta. Colei diretamente da saída do unittest. setUpe tearDownsão executados uma vez para cada testmétodo (duas vezes no total neste exemplo), mas setUpClasse tearDownClasssão executados apenas uma vez cada.
Benjamin Hodgson
15

Qual é a diferença entre setUp()e setUpClass()na unittestestrutura Python ?

A principal diferença (conforme observado na resposta de Benjamin Hodgson) é que setUpClassé chamado apenas uma vez e antes de todos os testes, enquanto setUpé chamado imediatamente antes de cada teste. (NB: o mesmo se aplica aos métodos equivalentes em outras estruturas de teste xUnit, não apenas em Python unittest.)

Da unittest documentação :

setUpClass()

Um método de classe chamado antes que os testes em uma classe individual sejam executados. setUpClass é chamado com a classe como o único argumento e deve ser decorado como um método de classe ():

@classmethod
def setUpClass(cls):
    ...

e:

setUp()

Método chamado para preparar o dispositivo de teste. Isso é chamado imediatamente antes de chamar o método de teste; diferente de AssertionError ou SkipTest, qualquer exceção gerada por esse método será considerada um erro, e não uma falha de teste. A implementação padrão não faz nada.

Por que a configuração seria tratada em um método e não no outro?

Esta parte da pergunta ainda não foi respondida. De acordo com meu comentário em resposta à resposta de Gearon, o setUpmétodo se destina a elementos do fixture que são comuns a todos os testes (para evitar a duplicação desse código em cada teste). Acho isso geralmente útil, pois a remoção da duplicação (geralmente) melhora a legibilidade e reduz a carga de manutenção.

O setUpClassmétodo é para elementos caros que você prefere ter que fazer apenas uma vez, como abrir uma conexão de banco de dados, abrir um arquivo temporário no sistema de arquivos, carregar uma biblioteca compartilhada para teste, etc. Fazer essas coisas antes de cada teste tornaria o conjunto de testes demais, então fazemos isso apenas uma vez antes de todos os testes. Esta é uma pequena degradação na independência dos testes, mas uma otimização necessária em algumas situações. Indiscutivelmente, não se deve fazer tais coisas em testes de unidade, pois geralmente é possível simular o banco de dados / sistema de arquivos / biblioteca / qualquer coisa sem usar a coisa real. Como tal, acho que setUpClassraramente é necessário. No entanto, é útil quando o teste dos exemplos acima (ou semelhantes) se torna necessário.

Biggsy
fonte