Share
Embed
Transcript
85 slides
-
Teste de software é o processo de avaliar o correto
funcionamento de sistema 4 -
Funcionais x Não funcionais • Feitos geralmente por devs •
O foco é testar requisitos funcionais • Testa a conformidade dos requisitos do cliente 12 • Podem ser feitos por stakeholders • Foco é testar requisitos não funcionais • Testa as expectativas do cliente -
Funcionais x Não funcionais • Testes unitários • Testes de
integração • Testes de sistema • Testes de contrato • Testes alpha/beta 13 • Testes de performance ◦ Teste de carregamento ◦ Teste de stress • Testes de segurança • Testes de usabilidade -
Testes unitários • Testa um componente de forma isolada ◦
Classe ◦ Método ◦ Função ◦ .. 15 -
16 public function testShouldBePalindrome () { $checker = new Checker();
$isPalindrome = $checker->isPalindrome('arara') $this->assertTrue($isPalindrome); } -
Testes de integração • Testa como diferentes partes do sistema
se comportam ◦ Controllers ◦ Models ◦ DB ◦ ... 17 -
18 public function testCreateUserByPOST() { $response = $this->json('POST', '/users', ['name'
=> 'Juca']); $this->assertStatus(201) ->assertJson([ 'created' => true ]); } -
Testes de Sistema • Testa como o comportamento do ponto
de vista do usuário ◦ Acessa uma página ◦ Clica nos links ◦ Preenche formulários ◦ … • Automatiza passos do usuário de uma forma programática 19 -
20 public function testBasicExample () { $user = factory(User:: class)->create();
$this->browse(function ($browser) use ($user) { $browser->visit( '/login') ->type( 'email', $user->email) ->type( 'password', 'password') ->press( 'Login') ->assertPathIs( '/home'); }); } -
Testes de contrato • Contrato é o que esperamos de
outra parte ◦ XML ◦ JSON ◦ ... • Testes de contrato validam ◦ respostas externas à nossa aplicação ◦ Objetos disponíveis 21 -
Testes alpha e beta • Consistem em criar um ambiente
semelhante ao de prod • Testa alpha ◦ Equipe dev ◦ Encontrar possíveis falhas ◦ Ver como as funcionalidades se comportam • Teste beta ◦ Usuários ◦ Feedbacks/Melhorias 24 -
Testes de carregamento • Testa a velocidade de carregamento de
uma página ◦ Google Page Speed 26 -
Testes de stress • Testa a capacidade da aplicação para
responder a múltiplas requisições ◦ Neotys ◦ ... 28 -
Testes de segurança • Busca possíveis brechas na segurança que
possam comprometer os usuários ◦ Arachni ◦ ... 30 -
Kent Beck: um pouco de história • Escreveu Sunit 1994
• Apresentou TDD na OOPSLA 1995 • Junto com Erich Gramma publicou “Test Infected” (2000) • TDD by Example 33 -
35 public function testShouldBePalindrome () { $checker = new Checker();
$isPalindrome = $checker->isPalindrome('arara') $this->assertTrue($isPalindrome); } -
36 class Checker { public function isPalindrome(string $word) : bool
{ $originalWord = str_replace(' ', '', strtolower($word)); $reversed = str_replace(' ', '', strrev($originalWord)); return $originalWord == $reversed; } } -
Detalhes sobre TDD Algumas curiosidades sobre a prática que geralmente
não entendemos de cara quando começamos a estudar 37 -
“ As suítes de testes não são tão fiéis ao
que estudamos na literatura. 40 -
Conhecendo a família xUnit Agora que já entendemos um pouco
de TDD, vamos falar sobre as suítes de testes. 4 -
Gerard Meszaros • Estudou as estruturas das principais suítes de
testes • Lançou xUnit Test Patterns (2007) 43 -
As fases do xUnit • Setup ◦ Preparamos o ambiente
para o teste • Exercise ◦ Simulamos o comportamento que esperamos testar • Verify ◦ Verificamos se ele teve o resultado esperado • Teardown ◦ Fazemos o ambiente voltar ao normal, como se o teste nunca tivesse acontecido 44 -
45 public function testShouldBeInactivated () { $this->user = User::create( $this->data);
$this->user->setStatus(UserStatus::INACTIVE); $this->assertFalse($this->user->isActive()); } public function teardown() { $this->user->destroy(); } -
46 public function testShouldBeInactivated () { $this->user = User::create( $this->data);
$this->user->setStatus(UserStatus::INACTIVE); $this->assertFalse($this->user->isActive()); } public function teardown() { $this->user->destroy(); } Setup Exercise Verify Teardown -
SUT e colaboradores • SUT (System Under Test) ◦ O
que está sendo testado em si ◦ Classe, método, função, etc • Colaboradores ◦ Interagem com o SUT durante a execução do teste 47 -
48 public function testShouldSumItemsValueAtCart () { $product = new Product(['value'
=> 20]); $item = new Item(['quantity' => 2, 'product' => $product]); $cart = new Cart(); $cart->addItem($item); $this->assertEquals(40, $cart->totalValue()); } -
49 public function testShouldSumItemsValueAtCart () { $product = new Product(['value'
=> 20]); $item = new Item(['quantity' => 2, 'product' => $product]); $cart = new Cart(); $cart->addItem($item); $this->assertEquals(40, $cart->totalValue()); } Colaboradores SUT -
Colaboradores • No exemplo anterior utilizamos as classes reais para
testar o SUT • Podemos substituir esses colaboradores reais por dublês, com isso, poderíamos chamar de Test Double 50 -
Test Doubles • Termo genérico para testes que substituem objetos
de produção por: ◦ Dummy; ◦ Fake; ◦ Stub; ◦ Spy; ◦ Mock; 52 -
Dummy • São utilizados para preencher listas de parâmetros, porém,
não são utilizados • Existem dois tipos: ◦ Dummy Object ◦ Dummy Value 53 -
54 public function depositMoney(float value, Account $account) { if ($value
<= 0) { throw new \InvalidArgumentException(); } $account->subtractCurrentBalance( $value); } -
55 /** * @expectedException InvalidArgumentException * */ public function testWhenValueLessOrEqualZeroShouldThrowAnException
() { $account = $this->prophesize(Account::class); $deposit = new Deposit(); $deposit->depositMoney(-10, $account->reveal(); } -
Fake • Substituem objetos para criar atalhos ou formas mais
fáceis de executar algo • Exemplo: InMemoryTestDatabase 56 -
57 class ClientRepositoryFake { private $clients = []; public function
save(Client $client) : Client { $id = count($this->clients); $client->setId($id); $this->clients[$id] = $client; return $client; } public function find(int $id) : Client { return $this->clients[$id]; } public function update(Client $client) : Client { $this->clients[$client->getId()] = $client; return $client; } } -
58 public function setup() { $client = new Client(['name' =>
'Gandalf', 'cpf' => '87511196098']); $this->clientRepository = new ClientRepositoryFake(); $this->clientRepository->save($user); } public function testAssociateShouldGenerateAccountNumber() { $client = $this->clientRepository->find(1); $account = new Account(); $account->setClient($client); $accountAssociator = AccountAssociator(); $accountAssociator->associateAccountToClient($account, $client); $this->assertNotNull($account->getNumber()); } -
Stub • Fornece respostas prontas programadas para chamadas específicas em
momento de execução • São utilizados na fase do setup 59 -
60 public function create() { if (!$this->validator->isCPFValid( $this->data['cpf']) { throw
new \Exception('Invalid CPF'); } return $this->repository->create(); } -
61 public function testShouldCreateAccountWhenCPFIsValid () { $validator = $this->prophesize(Validator::class); $validator->isCPFValid('23430222915')->willReturn(true);
$data = ['cpf' => '23430222915']; $account = new Account($data); $account->setValidator($validator->reveal()); $this->instanceOf(Account::class, $account->create()); } -
Spy • Possue controle sobre as chamadas que são feitas
em tempo de execução • Se foco é saber se determinado método/função foi chamado e como foi 62 -
63 class AddressReposity { public function save(Address $address) { $this->entityManager->persist($address);
$this->entityManager->flush(); } } -
64 public function shouldSaveNewAddress() { $em = $prophet->prophesize('Doctrine\ORM\EntityManager' ); $address
= new Address(); $addressRepository = new AddressRepository($em->reveal()); $addressRepository->save($address); $em->flush()->shouldHaveBeenCalled(); } -
Mock • São utilizados na fase do verify • Diferente
dos demais, é o único que faz a verificação por comportamento e não por estado 65 -
66 public function create() { if (!$this->validator->isCPFValid( $this->data['cpf']) { throw
new \Exception('Invalid CPF'); } return $this->repository->create(); } -
public function testShouldCreateAccountWhenCPFIsValid() { $validator = $this->prophesize(Validator::class); $validator->isCPFValid('23430222915') ->willReturn(true) ->shouldBeCalled($this->once());
$repository = $this->prophesize(Repository::class); $repository->create()->shouldBeCalled($this->once()); $data = ['cpf' => '23430222915']; $account = new Account($data); $account->setValidator($validator->reveal()); $account->setRepository($repository->reveal()); $account->create(); } -
BDD e TDD Essa duas siglas podem parecer mesma coisa,
porém não são 5 -
BDD • Behaviour Driven Development • É uma metodologia na
qual todos os stakeholders são envolvidos • Começa com especificações do cliente e termina no projeto entregue 69 -
71 BDD • Feature: … ◦ Scenario: … ▪ When:
… ▪ And: … ▪ Then: … • Especificações executáveis -
72 BDD x TDD • Começa descrevendo features e scenarios
• Envolve vários stakeholders • Foco no comportamento final • Começa escrevendo casos de teste • Envolve apenas devs • Foco na implementação -
Projetos legados • De dentro para fora • Testar apenas
código modificado • Testar apenas os requisitos • Adicionar apenas código testado • Quebrar dependências escondidas 74 -
Qual é a estratégia de testes ideal para o seu
projeto? 81 -
Referências • https:/ /martinfowler.com/bliki/InMemoryTestDatabase.ht ml • https:/ /martinfowler.com/bliki/TestDouble.html • https:/
/martinfowler.com/articles/mocksArentStubs.html • https:/ /www.amazon.com.br/Xunit-Test-Patterns-Refacto ring-Code/dp/0131495054 • https://www.softwaretestinghelp.com/functional-testing-vs-no n-functional-testing/ 83 -
Referências • https://docs.pact.io/ • https://martinfowler.com/bliki/ContractTest.html • https://martinfowler.com/articles/practical-test-pyramid.html • https://medium.com/edureka/types-of-software-testing-d7aa2 9090b5b
• https://hackr.io/blog/top-10-open-source-security-testing-tools -for-web-applications • https://danlimerick.wordpress.com/2012/04/25/tdd-when-up-t o-your-neck-in-legacy-code/ 84