def test_critico(self): """Verifica se o cálculo de golpes críticos está funcionando OK.""" res = (2 * self.poke1.lvl + 5)/(self.poke1.lvl + 5) chance = self.poke1.spd/512 maior_chance = chance + 0.001 valores_menores = [] valores_maiores = [] # Novamente usamos valores conhecidos para testar a unidade do # batalha.critico que usa números pseudo-aleatórios. Os primeiros # 100 valores serão menores que a chance e os outros 100, maiores. for i in range(100): valores_menores.append(random.uniform(0.0, chance)) valores_maiores.append(random.uniform(maior_chance, 1.0)) valores = valores_menores + valores_maiores a = RandomPoke() ataque = Ataque(a.gera_ataque()) with patch("batalha.random.uniform", side_effect=valores): # Em cada loop, a iteração chamará dano.critico duas # vezes, usando, então, dois valores do side_effect. for i in range(50): self.assertEqual(ataque.critico(self.poke1, 0), 1) self.assertEqual(ataque.critico(self.poke1, random.randint(1, 100)), res) for i in range(50): self.assertEqual(ataque.critico(self.poke1, 0), 1) self.assertEqual(ataque.critico(self.poke1, random.randint(1, 100)), 1) """
def teste_melhor_ataque(self): """ Vamos testar se a função melhor_ataque dá realmente o ataque com a melhor relação dano x acurácia testando todos os ataques do pokemon atacante no pokemon defensor.""" for j in range(100): # Cria um pokemon atacante e um defensor dados_atk = RandomPoke() dados_def = RandomPoke() atacante = Pokemon(dados_atk.gera()) defensor = Pokemon(dados_def.gera()) melhor = melhor_ataque(atacante, defensor) danos = [] if atacante.hp < atacante.hp_max/5: estado_critico = True else: estado_critico = False for ataque in atacante.ataques: if ataque.pp > 0 and estado_critico is False: dano = ataque.calcula_dano(atacante, defensor, is_basico=True) danos.append(dano * (ataque.acu*ataque.acu)/10000) elif ataque.pp > 0 and estado_critico is True: dano = ataque.calcula_dano(atacante, defensor, is_basico=True) # Caso não tire todo o hp, escolhe o que causa (em média) o maior # dano usando a relação dano x acurácia. if max(danos) < defensor.hp: melhor_dano = melhor.calcula_dano(atacante, defensor, is_basico=True) self.assertEqual(atacante.get_ataque(danos.index(max(danos))), melhor, 1)
def test_xml(self): """Verifica integridade e corretude dos xmls gerados.""" for i in range(300): data1 = RandomPoke() data2 = RandomPoke() dados1 = data1.gera() dados2 = data2.gera() poke1 = Pokemon(dados1) poke2 = Pokemon(dados2) # Testando to_xml bs_poke1 = poke1.to_xml() bs_poke2 = poke2.to_xml() data_teste1 = xml_to_poke(bs_poke1) data_teste2 = xml_to_poke(bs_poke2) for i in range(9): self.assertEqual(data_teste1[i], dados1[i]) self.assertEqual(data_teste2[i], dados2[i]) pos_atk = 9 # Posição da lista de ataques na lista de dados atk_dados1 = dados1[pos_atk] atk_dados2 = dados2[pos_atk] atk_test1 = data_teste1[pos_atk] atk_test2 = data_teste2[pos_atk] for i in range(len(poke1.ataques)): self.assertEqual(atk_dados1[i].nome, atk_test1[i].nome) self.assertEqual(atk_dados1[i].typ, atk_test1[i].typ) self.assertEqual(atk_dados1[i].acu, atk_test1[i].acu) self.assertEqual(atk_dados1[i].pwr, atk_test1[i].pwr) self.assertEqual(atk_dados1[i].pp, atk_test1[i].pp)
def setUp(self): """Inicializa os dois Pokémons aleatórios para os testes.""" sys.stdout = open(os.devnull, "w") # Suprime o output de batalha.py sys.stderr = sys.stdout self.a = RandomPoke() self.b = RandomPoke() self.poke1 = Pokemon(self.a.gera()) self.poke2 = Pokemon(self.b.gera()) self.struggle = Ataque(["Struggle", 0, 100, 50, 10])
def setUp(self): """Inicializa dados para teste.""" sys.stdout = open(os.devnull, "w") # Suprime o output de batalha.py sys.stderr = sys.stdout self.srv = Servidor(False) self.srv.app.config["TESTING"] = True self.app = self.srv.app.test_client() self.data1 = RandomPoke() self.data2 = RandomPoke() self.dados1 = self.data1.gera() self.dados2 = self.data2.gera() self.poke1 = Pokemon(self.dados1) self.poke2 = Pokemon(self.dados2)
def test_efetividade(self): """Verifica se o cálculo de efetividade é feito corretamente.""" # Novamente geramos um novo Pokémon para podermos realizar vários # testes com resultados diferentes. for i in range(100): a = RandomPoke() poke1 = Pokemon(a.gera()) ataque = Ataque(a.gera_ataque()) # Esta é a fórmula para calcular efetividade mult = ataque.typ.get_eff_contra(poke1.tipo1) if poke1.tipo2.nome != "Blank": mult *= ataque.typ.get_eff_contra(poke1.tipo2) self.assertEquals(mult, ataque.efetividade(poke1, False))
def test_realiza_ataque_e_calcula_dano(self): """Verifica se ataque e suas consequências ocorrem sem problemas.""" batalha.input = Mock(return_value="ok") # Geramos novos Pokémons para podermos realizar vários # testes sem acabar com todo o HP deles. for i in range(100): a = RandomPoke() b = RandomPoke() poke3 = poke1 = Pokemon(a.gera()) poke4 = poke2 = Pokemon(b.gera()) # Assumindo que o ataque sempre vai acertar with patch('batalha.random.uniform', return_value=1.0): # Aqui começa o cálculo do dano lvl = poke1.lvl ataque = Ataque(a.gera_ataque()) if ataque.typ.is_especial: atk = poke1.spc dfs = poke2.spc else: atk = poke1.atk dfs = poke2.dfs pp = ataque.pp hp = poke2.hp base = ataque.pwr eff = efetividade(ataque, poke2, False) dano = (2*lvl + 10)/250 * atk/dfs * base + 2 dano *= (stab(ataque, poke1) * critico(poke1, eff) * eff * aleatorio()) dano = int(dano) #Testa o dano.calcula_dano self.assertEqual(dano, calcula_dano(ataque, poke1, poke2)) if (dano > 0): poke1.remove_hp(dano) if ataque == self.struggle: dano //= 2 poke2.remove(hp.dano) # Verficamos se o Pokemon.realiza_ataque está # aplicando corretamente o dano conforme a fórmula. pokemon.input = Mock(return_value="\n") poke3.realiza_ataque(ataque, poke4) self.assertEquals(pp - 1, ataque.pp) self.assertEquals(poke1.hp, poke3.hp) self.assertEquals(poke2.hp, poke4.hp)
def gera_poke(self): """Gera pokemons tais que os ataques estão ordenados em ordem crescente de pwr e acu.""" t = RandomPoke() dados = t.gera() dados = dados[:9] #Tiramos a lista de ataques aleatórios ataque = [] rand_num = randint(1, 97) for i in range(4): #Criamos ataques ordenados ataque.append(self.gera_ataque(i + rand_num, i + rand_num, randint(1, 255))) ataques = [Ataque(ataque[i]) for i in range(4)] dados.append(ataques) poke = Pokemon(dados) #Agora nosso pokemón contém os ataques ordenados return poke
def gera_poke(self): """Gera pokemons tais que os ataques estão ordenados em ordem crescente de pwr e acu.""" t = RandomPoke() dados = t.gera() dados = dados[:9] #Tiramos a lista de ataques aleatórios ataque = [] rand_num = randint(1, 97) for i in range(4): #Criamos ataques ordenados ataque.append( self.gera_ataque(i + rand_num, i + rand_num, randint(1, 255))) ataques = [Ataque(ataque[i]) for i in range(4)] dados.append(ataques) poke = Pokemon(dados) #Agora nosso pokemón contém os ataques ordenados return poke
class PokeTestCase(unittest.TestCase): def setUp(self): """Inicializa o teste.""" sys.stdout = open(os.devnull, 'w') # Suprime o output de batalha.py self.ctrl = RandomPoke() self.test = Pokemon(self.ctrl.gera()) def test_pokemons(self): """Verifica se os valores do Pokémon coincidem com os anteriores.""" self.assertEqual(self.test.nome, self.ctrl.nome) self.assertEqual(self.test.lvl, self.ctrl.lvl) self.assertEqual(self.test.tipo1.numero, self.ctrl.tipo1) self.assertEqual(self.test.tipo2.numero, self.ctrl.tipo2) self.assertEqual(self.test.hp, self.ctrl.hp) self.assertEqual(self.test.atk, self.ctrl.atk) self.assertEqual(self.test.dfs, self.ctrl.dfs) self.assertEqual(self.test.spd, self.ctrl.spd) self.assertEqual(self.test.spc, self.ctrl.spc) def test_ataques(self): """Verifica se os ataques coincidem com os valores pré-estipulados.""" for i in range(len(self.test.ataques)): ataque = self.test.ataques[i] self.assertEqual(ataque.nome, self.ctrl.ataques[i][0]) self.assertEqual(ataque.typ.numero, self.ctrl.ataques[i][1]) self.assertEqual(ataque.acu, self.ctrl.ataques[i][2]) self.assertEqual(ataque.pwr, self.ctrl.ataques[i][3]) self.assertEqual(ataque.pp, self.ctrl.ataques[i][4]) def test_acertou(self): chance = (self.test.ataques[0].acu * self.test.ataques[0].acu)/10000 maior_chance = chance + 0.001 valores_menores = [] valores_maiores = [] for i in range(100): valores_menores.append(random.uniform(0, chance)) valores_maiores.append(random.uniform(maior_chance, 1)) valores = valores_menores + valores_maiores # Usamos valores conhecidos para testar a unidade do .acertou # que usa números pseudo-aleatórios. with patch("batalha.random.uniform", side_effect=valores): for i in range(100): self.assertTrue(self.test.ataques[0].acertou()) for i in range(100): self.assertFalse(self.test.ataques[0].acertou()) def tearDown(self): """Finaliza o teste.""" sys.stdout.close() # Fechando o os.devnull sys.stdout = sys.__stdout__
def teste_melhor_ataque(self): """ Vamos testar se a função melhor_ataque dá realmente o ataque com a melhor relação dano x acurácia testando todos os ataques do pokemon atacante no pokemon defensor.""" for j in range(100): # Cria um pokemon atacante e um defensor dados_atk = RandomPoke() dados_def = RandomPoke() atacante = Pokemon(dados_atk.gera()) defensor = Pokemon(dados_def.gera()) melhor = melhor_ataque(atacante, defensor) danos = [] if atacante.hp < atacante.hp_max / 5: estado_critico = True else: estado_critico = False for ataque in atacante.ataques: if ataque.pp > 0 and estado_critico is False: dano = ataque.calcula_dano(atacante, defensor, basico=True) danos.append(dano * (ataque.acu * ataque.acu) / 10000) elif ataque.pp > 0 and estado_critico is True: dano = ataque.calcula_dano(atacante, defensor, basico=True) # Caso não tire todo o hp, escolhe o que causa (em média) o maior # dano usando a relação dano x acurácia. if max(danos) < defensor.hp: melhor_dano = melhor.calcula_dano(atacante, defensor, basico=True) self.assertEqual(atacante.get_ataque(danos.index(max(danos))), melhor, 1)
class PokeTestCase(unittest.TestCase): def setUp(self): """Inicializa o teste.""" sys.stdout = open(os.devnull, 'w') # Suprime o output de batalha.py self.ctrl = RandomPoke() self.test = Pokemon(self.ctrl.gera()) def test_pokemons(self): """Verifica se os valores do Pokémon coincidem com os anteriores.""" self.assertEqual(self.test.nome, self.ctrl.nome) self.assertEqual(self.test.lvl, self.ctrl.lvl) self.assertEqual(self.test.tipo1.numero, self.ctrl.tipo1) self.assertEqual(self.test.tipo2.numero, self.ctrl.tipo2) self.assertEqual(self.test.hp, self.ctrl.hp) self.assertEqual(self.test.atk, self.ctrl.atk) self.assertEqual(self.test.dfs, self.ctrl.dfs) self.assertEqual(self.test.spd, self.ctrl.spd) self.assertEqual(self.test.spc, self.ctrl.spc) def test_ataques(self): """Verifica se os ataques coincidem com os valores pré-estipulados.""" for i in range(len(self.test.ataques)): ataque = self.test.ataques[i] self.assertEqual(ataque.nome, self.ctrl.ataques[i][0]) self.assertEqual(ataque.typ.numero, self.ctrl.ataques[i][1]) self.assertEqual(ataque.acu, self.ctrl.ataques[i][2]) self.assertEqual(ataque.pwr, self.ctrl.ataques[i][3]) self.assertEqual(ataque.pp, self.ctrl.ataques[i][4]) def test_acertou(self): chance = (self.test.ataques[0].acu * self.test.ataques[0].acu) / 10000 maior_chance = chance + 0.001 valores_menores = [] valores_maiores = [] for i in range(100): valores_menores.append(random.uniform(0, chance)) valores_maiores.append(random.uniform(maior_chance, 1)) valores = valores_menores + valores_maiores # Usamos valores conhecidos para testar a unidade do .acertou # que usa números pseudo-aleatórios. with patch("batalha.random.uniform", side_effect=valores): for i in range(100): self.assertTrue(self.test.ataques[0].acertou()) for i in range(100): self.assertFalse(self.test.ataques[0].acertou()) def tearDown(self): """Finaliza o teste.""" sys.stdout.close() # Fechando o os.devnull sys.stdout = sys.__stdout__
def test_realiza_ataque_e_calcula_dano(self): """Verifica se ataque e suas consequências ocorrem sem problemas.""" batalha.input = Mock(return_value="ok") # Geramos novos Pokémons para podermos realizar vários # testes sem acabar com todo o HP deles. for i in range(100): a = RandomPoke() b = RandomPoke() poke3 = poke1 = Pokemon(a.gera()) poke4 = poke2 = Pokemon(b.gera()) # Assumindo que o ataque sempre vai acertar with patch('batalha.random.uniform', return_value=1.0): # Aqui começa o cálculo do dano lvl = poke1.lvl ataque = Ataque(a.gera_ataque()) if ataque.typ.especial: atk = poke1.spc dfs = poke2.spc else: atk = poke1.atk dfs = poke2.dfs pp = ataque.pp hp = poke2.hp base = ataque.pwr eff = efetividade(ataque, poke2, False) dano = (2 * lvl + 10) / 250 * atk / dfs * base + 2 dano *= (stab(ataque, poke1) * critico(poke1, eff) * eff * aleatorio()) dano = int(dano) #Testa o dano.calcula_dano self.assertEqual(dano, calcula_dano(ataque, poke1, poke2)) if (dano > 0): poke1.remove_hp(dano) if ataque == self.struggle: dano //= 2 poke2.remove(hp.dano) # Verficamos se o Pokemon.realiza_ataque está # aplicando corretamente o dano conforme a fórmula. pokemon.input = Mock(return_value="\n") poke3.realiza_ataque(ataque, poke4) self.assertEquals(pp - 1, ataque.pp) self.assertEquals(poke1.hp, poke3.hp) self.assertEquals(poke2.hp, poke4.hp)
class DanoTestCase(unittest.TestCase): def setUp(self): sys.stdout = open(os.devnull, "w") # Suprime o output de batalha.py sys.stderr = sys.stdout self.a = RandomPoke() self.poke1 = Pokemon(self.a.gera()) def test_critico(self): """Verifica se o cálculo de golpes críticos está funcionando OK.""" res = (2 * self.poke1.lvl + 5)/(self.poke1.lvl + 5) chance = self.poke1.spd/512 maior_chance = chance + 0.001 valores_menores = [] valores_maiores = [] # Novamente usamos valores conhecidos para testar a unidade do # batalha.critico que usa números pseudo-aleatórios. Os primeiros # 100 valores serão menores que a chance e os outros 100, maiores. for i in range(100): valores_menores.append(random.uniform(0.0, chance)) valores_maiores.append(random.uniform(maior_chance, 1.0)) valores = valores_menores + valores_maiores a = RandomPoke() ataque = Ataque(a.gera_ataque()) with patch("batalha.random.uniform", side_effect=valores): # Em cada loop, a iteração chamará dano.critico duas # vezes, usando, então, dois valores do side_effect. for i in range(50): self.assertEqual(ataque.critico(self.poke1, 0), 1) self.assertEqual(ataque.critico(self.poke1, random.randint(1, 100)), res) for i in range(50): self.assertEqual(ataque.critico(self.poke1, 0), 1) self.assertEqual(ataque.critico(self.poke1, random.randint(1, 100)), 1) """ self.assertRaises(AttributeError, critico, self.poke1.nome, None) self.assertRaises(AttributeError, critico, self.poke1.hp, None) self.assertRaises(AttributeError, critico, None, self.poke1.nome) self.assertRaises(AttributeError, critico, None, self.poke1.hp) """ def test_efetividade(self): """Verifica se o cálculo de efetividade é feito corretamente.""" # Novamente geramos um novo Pokémon para podermos realizar vários # testes com resultados diferentes. for i in range(100): a = RandomPoke() poke1 = Pokemon(a.gera()) ataque = Ataque(a.gera_ataque()) # Esta é a fórmula para calcular efetividade mult = ataque.typ.get_eff_contra(poke1.tipo1) if poke1.tipo2.nome != "Blank": mult *= ataque.typ.get_eff_contra(poke1.tipo2) self.assertEquals(mult, ataque.efetividade(poke1, False)) def test_stab(self): ataque = self.poke1.ataques[0] not_typ = 0 while not_typ == ataque.typ: not_typ = random.randint(0, 255) # É esperado que se o typ do ataque for igual ao tipo1 ou tipo2 # do atacante, dano.stab devolve 1.5. Caso contrário, devolve 1. poke = "pokemon.Pokemon." with patch(poke + "tipo1", PropertyMock(return_value=ataque.typ)): with patch(poke + "tipo2", PropertyMock(return_value=ataque.typ)): self.assertEqual(ataque.stab(self.poke1), 1.5) with patch(poke + "tipo2", PropertyMock(return_value=not_typ)): self.assertEqual(ataque.stab(self.poke1), 1.5) with patch(poke + "tipo2", PropertyMock(return_value=ataque.typ)): with patch(poke + "tipo1", PropertyMock(return_value=not_typ)): self.assertEqual(ataque.stab(self.poke1), 1.5) with patch(poke + "tipo2", PropertyMock(return_value=not_typ)): self.assertEqual(ataque.stab(self.poke1), 1) def tearDown(self): sys.stdout.close() # Fechando o os.devnull sys.stdout = sys.__stdout__ sys.stderr = sys.__stderr__
class BatalhaTestCase(unittest.TestCase): def setUp(self): """Inicializa os dois Pokémons aleatórios para os testes.""" sys.stdout = open(os.devnull, "w") # Suprime o output de batalha.py sys.stderr = sys.stdout self.a = RandomPoke() self.b = RandomPoke() self.poke1 = Pokemon(self.a.gera()) self.poke2 = Pokemon(self.b.gera()) self.struggle = Ataque(["Struggle", 0, 100, 50, 10]) def test_quem_comeca(self): """Verifica se a função quem_comeca retorna a tupla com o Pokemon de maior SPD primeiro.""" primeiro = (self.poke1 if self.poke1.spd > self.poke2.spd else self.poke2) segundo = self.poke2 if primeiro == self.poke1 else self.poke1 self.assertEqual(quem_comeca(primeiro, segundo), primeiro) self.assertEqual(quem_comeca(segundo, primeiro), primeiro) self.assertRaises(AttributeError, quem_comeca, None, None) self.assertRaises(AttributeError, quem_comeca, self.poke1, None) self.assertRaises(AttributeError, quem_comeca, None, self.poke1) def test_mostra(self): """Apenas verifica se a função levanta erros de atributos.""" self.assertRaises(AttributeError, mostra_pokemons, None, None) self.assertRaises(AttributeError, mostra_pokemons, self.poke1, None) self.assertRaises(AttributeError, mostra_pokemons, None, self.poke1) def test_escolhe_ataque(self): """Faz diversas verificações de input na escolha dos ataques.""" # Primeiro testamos como se nosso pokemons estivesse sem pp. # O comportamento esperado é que utilize Struggle. batalha.input = Mock(return_value="ok") with patch("pokemon.Pokemon.todos_ataques_sem_pp", return_value=True): self.assertEqual(self.poke2.todos_ataques_sem_pp(), True) self.assertEqual((escolhe_ataque(self.poke1, self.poke2)).nome, self.struggle.nome) # Testando se escolhe_ataque está retornando os ataques corretos for i in range(len(self.poke1.ataques)): batalha.input = Mock(return_value=(i + 1)) self.assertEqual(escolhe_ataque(self.poke1, self.poke2), self.poke1.ataques[i]) # Nesse ponto o escolhe_ataque receberá de input 4 valores "errados" # e um certo. O comportamento esperado é que a função não levante # exceções com os valores errados e execute normalmente quando chegar # o correto. valores_errados = [ self.poke1.nome, random.uniform(-100, 100), 5, -1, 1 ] batalha.input = Mock(side_effect=valores_errados) self.assertTrue( escolhe_ataque(self.poke1, self.poke2) in self.poke1.ataques) def test_realiza_ataque_e_calcula_dano(self): """Verifica se ataque e suas consequências ocorrem sem problemas.""" batalha.input = Mock(return_value="ok") # Geramos novos Pokémons para podermos realizar vários # testes sem acabar com todo o HP deles. for i in range(100): a = RandomPoke() b = RandomPoke() poke3 = poke1 = Pokemon(a.gera()) poke4 = poke2 = Pokemon(b.gera()) # Assumindo que o ataque sempre vai acertar with patch('batalha.random.uniform', return_value=1.0): # Aqui começa o cálculo do dano lvl = poke1.lvl ataque = Ataque(a.gera_ataque()) if ataque.typ.especial: atk = poke1.spc dfs = poke2.spc else: atk = poke1.atk dfs = poke2.dfs pp = ataque.pp hp = poke2.hp base = ataque.pwr eff = efetividade(ataque, poke2, False) dano = (2 * lvl + 10) / 250 * atk / dfs * base + 2 dano *= (stab(ataque, poke1) * critico(poke1, eff) * eff * aleatorio()) dano = int(dano) #Testa o dano.calcula_dano self.assertEqual(dano, calcula_dano(ataque, poke1, poke2)) if (dano > 0): poke1.remove_hp(dano) if ataque == self.struggle: dano //= 2 poke2.remove(hp.dano) # Verficamos se o Pokemon.realiza_ataque está # aplicando corretamente o dano conforme a fórmula. pokemon.input = Mock(return_value="\n") poke3.realiza_ataque(ataque, poke4) self.assertEquals(pp - 1, ataque.pp) self.assertEquals(poke1.hp, poke3.hp) self.assertEquals(poke2.hp, poke4.hp) def tearDown(self): """Encerra os testes.""" sys.stdout.close() # Fechando o os.devnull sys.stdout = sys.__stdout__ sys.stderr = sys.__stderr__
def setUp(self): sys.stdout = open(os.devnull, "w") # Suprime o output de batalha.py sys.stderr = sys.stdout self.a = RandomPoke() self.poke1 = Pokemon(self.a.gera())
class MultiplayerTestCase(unittest.TestCase): def setUp(self): """Inicializa dados para teste.""" sys.stdout = open(os.devnull, "w") # Suprime o output de batalha.py sys.stderr = sys.stdout self.srv = Servidor(False) self.srv.app.config["TESTING"] = True self.app = self.srv.app.test_client() self.data1 = RandomPoke() self.data2 = RandomPoke() self.dados1 = self.data1.gera() self.dados2 = self.data2.gera() self.poke1 = Pokemon(self.dados1) self.poke2 = Pokemon(self.dados2) def test_servidor_ataca(self): """Teste de ataques do servidor.""" t = self.quem_primeiro() poke_servidor = t["Servidor"] poke_cliente = t["Cliente"] # dados_servidor contém as especificações de um Pokémón no formato # recebido por le_pokemon(). dados_servidor = t["Dados do servidor"] # Usamos esse patch para a função le_pokemon() retornar o # poke_servidor ao invés de ler algum outro do stdin. with patch("entrada.input", side_effect=dados_servidor): # Para termos controle sobre os resultados das batalhas with patch("batalha.random.uniform", return_value=float(0.5)): # O número do ataque nos será pedido pelo stdin; vamos escolher # sempre o primeiro. with patch("batalha.input", return_value=1): pokemon.input = Mock(return_value="\n") # Façamos primeiro o teste multiplayer bs_multi = self.app.post("/battle/", data=poke_cliente.to_xml()) # Removendo o b" " bs_multi = self.padroniza(bs_multi.data) # Vamos realizar a mesma batalha agora no modo offline poke_servidor.realiza_ataque( escolhe_ataque(poke_servidor, poke_cliente), poke_cliente) # Vamos testar se os resultados são os mesmo se simularmos # no modo offline, já testado pelos outros arquivos de # teste e plenamente operante. self.assertEqual(cria_bs(poke_cliente, poke_servidor), bs_multi) def test_cliente_ataca(self): """Procedemos da mesma maneira que no método test_servidor_ataca(), mas aqui também testamos o ataque do cliente.""" t = self.quem_primeiro() poke_servidor = t["Servidor"] poke_cliente = t["Cliente"] dados_servidor = t["Dados do servidor"] # Mesma coisa que no método teste_servidor_ataca with patch("entrada.input", side_effect=dados_servidor): with patch("batalha.random.uniform", return_value=float(0.5)): with patch("batalha.input", return_value=1): pokemon.input = Mock(return_value="\n") self.app.post("/battle/", data=poke_cliente.to_xml()) id = escolhe_ataque(poke_cliente, poke_servidor) id = poke_cliente.ataques.index(id) + 1 multi_bs = self.app.post("/battle/attack/" + str(id)) multi_bs = self.padroniza(multi_bs.data) poke_servidor.realiza_ataque( escolhe_ataque(poke_servidor, poke_cliente), poke_cliente) poke_cliente.realiza_ataque( poke_cliente.get_ataque(id - 1), poke_servidor) if poke_cliente.hp > 0 and poke_servidor.hp > 0: ataque = escolhe_ataque(poke_servidor, poke_cliente) poke_servidor.realiza_ataque(ataque, poke_cliente) off_bs = cria_bs(poke_cliente, poke_servidor) self.assertEqual(off_bs, multi_bs) def test_shutdown(self): """Verifica se o programa está sendo encerrado corretamente.""" self.assertRaises(RuntimeError, self.app.post, "/shutdown/") def test_locked(self): """Como no setUp iniciamos o app, todas as vezes que tentarmos mandar um POST para /battle/ resultará no erro 423.""" self.srv.app.config["TESTING"] = False with patch("entrada.input", side_effect=self.data1.gera_linear()): self.app.post("/battle/") erro_423 = self.app.post("/battle/") erro_423 = self.padroniza(erro_423.data) self.assertTrue("Locked" in erro_423) def test_xml(self): """Verifica integridade e corretude dos xmls gerados.""" for i in range(300): data1 = RandomPoke() data2 = RandomPoke() dados1 = data1.gera() dados2 = data2.gera() poke1 = Pokemon(dados1) poke2 = Pokemon(dados2) # Testando to_xml bs_poke1 = poke1.to_xml() bs_poke2 = poke2.to_xml() data_teste1 = xml_to_poke(bs_poke1) data_teste2 = xml_to_poke(bs_poke2) for i in range(9): self.assertEqual(data_teste1[i], dados1[i]) self.assertEqual(data_teste2[i], dados2[i]) pos_atk = 9 # Posição da lista de ataques na lista de dados atk_dados1 = dados1[pos_atk] atk_dados2 = dados2[pos_atk] atk_test1 = data_teste1[pos_atk] atk_test2 = data_teste2[pos_atk] for i in range(len(poke1.ataques)): self.assertEqual(atk_dados1[i].nome, atk_test1[i].nome) self.assertEqual(atk_dados1[i].typ, atk_test1[i].typ) self.assertEqual(atk_dados1[i].acu, atk_test1[i].acu) self.assertEqual(atk_dados1[i].pwr, atk_test1[i].pwr) self.assertEqual(atk_dados1[i].pp, atk_test1[i].pp) def padroniza(self, data): """Converte o resultado da requisição em uma string BattleState.""" data = str(data).replace("b'", "") data = data[:-1] return data def quem_primeiro(self): """Usa dicionários para retornar nessa ordem o Pokémon gerado aleatoriamente que ataca primeiro no jogo, o que ataca em segundo e, por fim, uma lista com os dados do Pokémon a ser usado pelo servidor, que é o que começa atacando nestes testes""" if quem_comeca(self.poke1, self.poke2) == self.poke1: return { "Servidor": self.poke1, "Cliente": self.poke2, "Dados do servidor": self.data1.gera_linear() } else: return { "Servidor": self.poke2, "Cliente": self.poke1, "Dados do servidor": self.data2.gera_linear() } def tearDown(self): """Encerra os testes.""" sys.stdout.close() # Fechando o os.devnull sys.stdout = sys.__stdout__ sys.stderr = sys.__stderr__
class BatalhaTestCase(unittest.TestCase): def setUp(self): """Inicializa os dois Pokémons aleatórios para os testes.""" sys.stdout = open(os.devnull, "w") # Suprime o output de batalha.py sys.stderr = sys.stdout self.a = RandomPoke() self.b = RandomPoke() self.poke1 = Pokemon(self.a.gera()) self.poke2 = Pokemon(self.b.gera()) self.struggle = Ataque(["Struggle", 0, 100, 50, 10]) def test_quem_comeca(self): """Verifica se a função quem_comeca retorna a tupla com o Pokemon de maior SPD primeiro.""" primeiro = (self.poke1 if self.poke1.spd > self.poke2.spd else self.poke2) segundo = self.poke2 if primeiro == self.poke1 else self.poke1 self.assertEqual(quem_comeca(primeiro, segundo), primeiro) self.assertEqual(quem_comeca(segundo, primeiro), primeiro) self.assertRaises(AttributeError, quem_comeca, None, None) self.assertRaises(AttributeError, quem_comeca, self.poke1, None) self.assertRaises(AttributeError, quem_comeca, None, self.poke1) def test_mostra(self): """Apenas verifica se a função levanta erros de atributos.""" self.assertRaises(AttributeError, mostra_pokemons, None, None) self.assertRaises(AttributeError, mostra_pokemons, self.poke1, None) self.assertRaises(AttributeError, mostra_pokemons, None, self.poke1) def test_escolhe_ataque(self): """Faz diversas verificações de input na escolha dos ataques.""" # Primeiro testamos como se nosso pokemons estivesse sem pp. # O comportamento esperado é que utilize Struggle. batalha.input = Mock(return_value="ok") with patch("pokemon.Pokemon.todos_ataques_sem_pp", return_value=True): self.assertEqual(self.poke2.todos_ataques_sem_pp(), True) self.assertEqual((escolhe_ataque(self.poke1, self.poke2)).nome, self.struggle.nome) # Testando se escolhe_ataque está retornando os ataques corretos for i in range(len(self.poke1.ataques)): batalha.input = Mock(return_value=(i+1)) self.assertEqual(escolhe_ataque(self.poke1, self.poke2), self.poke1.ataques[i]) # Nesse ponto o escolhe_ataque receberá de input 4 valores "errados" # e um certo. O comportamento esperado é que a função não levante # exceções com os valores errados e execute normalmente quando chegar # o correto. valores_errados = [self.poke1.nome, random.uniform(-100, 100), 5, -1, 1] batalha.input = Mock(side_effect=valores_errados) self.assertTrue(escolhe_ataque(self.poke1, self.poke2) in self.poke1.ataques) def test_realiza_ataque_e_calcula_dano(self): """Verifica se ataque e suas consequências ocorrem sem problemas.""" batalha.input = Mock(return_value="ok") # Geramos novos Pokémons para podermos realizar vários # testes sem acabar com todo o HP deles. for i in range(100): a = RandomPoke() b = RandomPoke() poke3 = poke1 = Pokemon(a.gera()) poke4 = poke2 = Pokemon(b.gera()) # Assumindo que o ataque sempre vai acertar with patch('batalha.random.uniform', return_value=1.0): # Aqui começa o cálculo do dano lvl = poke1.lvl ataque = Ataque(a.gera_ataque()) if ataque.typ.is_especial: atk = poke1.spc dfs = poke2.spc else: atk = poke1.atk dfs = poke2.dfs pp = ataque.pp hp = poke2.hp base = ataque.pwr eff = efetividade(ataque, poke2, False) dano = (2*lvl + 10)/250 * atk/dfs * base + 2 dano *= (stab(ataque, poke1) * critico(poke1, eff) * eff * aleatorio()) dano = int(dano) #Testa o dano.calcula_dano self.assertEqual(dano, calcula_dano(ataque, poke1, poke2)) if (dano > 0): poke1.remove_hp(dano) if ataque == self.struggle: dano //= 2 poke2.remove(hp.dano) # Verficamos se o Pokemon.realiza_ataque está # aplicando corretamente o dano conforme a fórmula. pokemon.input = Mock(return_value="\n") poke3.realiza_ataque(ataque, poke4) self.assertEquals(pp - 1, ataque.pp) self.assertEquals(poke1.hp, poke3.hp) self.assertEquals(poke2.hp, poke4.hp) def tearDown(self): """Encerra os testes.""" sys.stdout.close() # Fechando o os.devnull sys.stdout = sys.__stdout__ sys.stderr = sys.__stderr__
def setUp(self): """Inicializa o teste.""" sys.stdout = open(os.devnull, 'w') # Suprime o output de batalha.py self.ctrl = RandomPoke() self.test = Pokemon(self.ctrl.gera())
class MultiplayerTestCase(unittest.TestCase): def setUp(self): """Inicializa dados para teste.""" sys.stdout = open(os.devnull, "w") # Suprime o output de batalha.py sys.stderr = sys.stdout self.srv = Servidor(False) self.srv.app.config["TESTING"] = True self.app = self.srv.app.test_client() self.data1 = RandomPoke() self.data2 = RandomPoke() self.dados1 = self.data1.gera() self.dados2 = self.data2.gera() self.poke1 = Pokemon(self.dados1) self.poke2 = Pokemon(self.dados2) def test_servidor_ataca(self): """Teste de ataques do servidor.""" t = self.quem_primeiro() poke_servidor = t["Servidor"] poke_cliente = t["Cliente"] # dados_servidor contém as especificações de um Pokémón no formato # recebido por le_pokemon(). dados_servidor = t["Dados do servidor"] # Usamos esse patch para a função le_pokemon() retornar o # poke_servidor ao invés de ler algum outro do stdin. with patch("entrada.input", side_effect=dados_servidor): # Para termos controle sobre os resultados das batalhas with patch("batalha.random.uniform", return_value=float(0.5)): # O número do ataque nos será pedido pelo stdin; vamos escolher # sempre o primeiro. with patch("batalha.input", return_value=1): pokemon.input = Mock(return_value="\n") # Façamos primeiro o teste multiplayer bs_multi = self.app.post("/battle/", data=poke_cliente.to_xml()) # Removendo o b" " bs_multi = self.padroniza(bs_multi.data) # Vamos realizar a mesma batalha agora no modo offline poke_servidor.realiza_ataque(escolhe_ataque(poke_servidor, poke_cliente), poke_cliente) # Vamos testar se os resultados são os mesmo se simularmos # no modo offline, já testado pelos outros arquivos de # teste e plenamente operante. self.assertEqual(cria_bs(poke_cliente, poke_servidor), bs_multi) def test_cliente_ataca(self): """Procedemos da mesma maneira que no método test_servidor_ataca(), mas aqui também testamos o ataque do cliente.""" t = self.quem_primeiro() poke_servidor = t["Servidor"] poke_cliente = t["Cliente"] dados_servidor = t["Dados do servidor"] # Mesma coisa que no método teste_servidor_ataca with patch("entrada.input", side_effect=dados_servidor): with patch("batalha.random.uniform", return_value=float(0.5)): with patch("batalha.input", return_value=1): pokemon.input = Mock(return_value="\n") self.app.post("/battle/", data=poke_cliente.to_xml()) id = escolhe_ataque(poke_cliente, poke_servidor) id = poke_cliente.ataques.index(id) + 1 multi_bs = self.app.post("/battle/attack/" + str(id)) multi_bs = self.padroniza(multi_bs.data) poke_servidor.realiza_ataque(escolhe_ataque(poke_servidor, poke_cliente), poke_cliente) poke_cliente.realiza_ataque(poke_cliente.get_ataque(id-1), poke_servidor) if poke_cliente.hp > 0 and poke_servidor.hp > 0: ataque = escolhe_ataque(poke_servidor, poke_cliente) poke_servidor.realiza_ataque(ataque, poke_cliente) off_bs = cria_bs(poke_cliente, poke_servidor) self.assertEqual(off_bs, multi_bs) def test_shutdown(self): """Verifica se o programa está sendo encerrado corretamente.""" self.assertRaises(RuntimeError, self.app.post, "/shutdown/") def test_locked(self): """Como no setUp iniciamos o app, todas as vezes que tentarmos mandar um POST para /battle/ resultará no erro 423.""" self.srv.app.config["TESTING"] = False with patch("entrada.input", side_effect=self.data1.gera_linear()): self.app.post("/battle/") erro_423 = self.app.post("/battle/") erro_423 = self.padroniza(erro_423.data) self.assertTrue("Locked" in erro_423) def test_xml(self): """Verifica integridade e corretude dos xmls gerados.""" for i in range(300): data1 = RandomPoke() data2 = RandomPoke() dados1 = data1.gera() dados2 = data2.gera() poke1 = Pokemon(dados1) poke2 = Pokemon(dados2) # Testando to_xml bs_poke1 = poke1.to_xml() bs_poke2 = poke2.to_xml() data_teste1 = xml_to_poke(bs_poke1) data_teste2 = xml_to_poke(bs_poke2) for i in range(9): self.assertEqual(data_teste1[i], dados1[i]) self.assertEqual(data_teste2[i], dados2[i]) pos_atk = 9 # Posição da lista de ataques na lista de dados atk_dados1 = dados1[pos_atk] atk_dados2 = dados2[pos_atk] atk_test1 = data_teste1[pos_atk] atk_test2 = data_teste2[pos_atk] for i in range(len(poke1.ataques)): self.assertEqual(atk_dados1[i].nome, atk_test1[i].nome) self.assertEqual(atk_dados1[i].typ, atk_test1[i].typ) self.assertEqual(atk_dados1[i].acu, atk_test1[i].acu) self.assertEqual(atk_dados1[i].pwr, atk_test1[i].pwr) self.assertEqual(atk_dados1[i].pp, atk_test1[i].pp) def padroniza(self, data): """Converte o resultado da requisição em uma string BattleState.""" data = str(data).replace("b'", "") data = data[:-1] return data def quem_primeiro(self): """Usa dicionários para retornar nessa ordem o Pokémon gerado aleatoriamente que ataca primeiro no jogo, o que ataca em segundo e, por fim, uma lista com os dados do Pokémon a ser usado pelo servidor, que é o que começa atacando nestes testes""" if quem_comeca(self.poke1, self.poke2) == self.poke1: return {"Servidor": self.poke1, "Cliente": self.poke2, "Dados do servidor": self.data1.gera_linear()} else: return {"Servidor": self.poke2, "Cliente": self.poke1, "Dados do servidor": self.data2.gera_linear()} def tearDown(self): """Encerra os testes.""" sys.stdout.close() # Fechando o os.devnull sys.stdout = sys.__stdout__ sys.stderr = sys.__stderr__