Estou integrando os testes de um sistema, usando apenas as APIs públicas. Eu tenho um teste que se parece com isso:
def testAllTheThings():
email = create_random_email()
password = create_random_password()
ok = account_signup(email, password)
assert ok
url = wait_for_confirmation_email()
assert url
ok = account_verify(url)
assert ok
token = get_auth_token(email, password)
a = do_A(token)
assert a
b = do_B(token, a)
assert b
c = do_C(token, b)
# ...and so on...
Basicamente, estou tentando testar todo o "fluxo" de uma única transação. Cada etapa do fluxo depende da etapa anterior ter êxito. Como estou me restringindo à API externa, não posso simplesmente colocar valores no banco de dados.
Então, ou eu tenho um método de teste realmente longo que faz `A; afirmar; B; afirmar; C; assert ... ", ou divido-o em métodos de teste separados, em que cada método de teste precisa dos resultados do teste anterior antes que ele possa fazer o seguinte:
def testAccountSignup():
# etc.
return email, password
def testAuthToken():
email, password = testAccountSignup()
token = get_auth_token(email, password)
assert token
return token
def testA():
token = testAuthToken()
a = do_A(token)
# etc.
Eu acho que isso cheira. Existe uma maneira melhor de escrever esses testes?
Eu separaria o código de teste do código de instalação. Possivelmente:
Lembre-se de que todas as informações aleatórias geradas devem ser incluídas na asserção, caso falhem; caso contrário, seu teste poderá não ser reproduzível. Eu posso até gravar a semente aleatória usada. Além disso, sempre que um caso aleatório falhar, adicione essa entrada específica como um teste codificado para impedir a regressão.
fonte
Não é muito melhor, mas você pode pelo menos separar o código de instalação da afirmação do código. Escreva um método separado que conte toda a história passo a passo e escolha um parâmetro para controlar quantas etapas deve ser executada. Então cada teste pode dizer algo como
simulate 4
ousimulate 10
e, em seguida, afirmar o que testar.fonte
Bem, talvez eu não obtenha a sintaxe do Python aqui por "código de ar", mas acho que você entendeu: você pode implementar uma função geral como esta:
o que permitirá que você escreva seus testes assim:
Obviamente, é discutível se a perda de legibilidade dessa abordagem vale a pena usá-la, mas reduz um pouco o código padrão.
fonte