You are viewing an old revision of this post, from October 26, 2023 @ 10:04:43. See below for differences between this version and the current revision.
(Este é um post que publiquei no antigo blog da SEA Tecnologia. Como ainda é relevante, resolvi republicá-lo.)
E-Plamtax foi um projeto muito positivo que executamos para a Força Aérea. A equipe do E-Plamtax aprendeu muitas coisas no projeto, mas muitas dessas aprendizagens ficaram guardadas conosco. Uma das mais interessantes é a criação de utilitários de teste.
Utilitários de teste são uma maneira de reaproveitar código em testes unitários. Usualmente, isso é feito utilizando os métodos setUp
ou @Before
dos casos de teste, mas isso tem algumas desvantagens. Por exemplo, em um caso de teste, podemos ter a seguinte inicialização:
private Address address;
private AddressDAO addressDAO;
@Before
public void setUp() {
address = new Address();
address.setStreet("Rua fulano");
address.setNumber("123/A");
addressDAO = new AddressDAO();
}
Code language: PHP (php)
Essa inicialização funciona bem no teste abaixo…
@Test
public void testGetAllAddresses(){
addressDAO.addAddress(address);
List<Address> addresses = addressDAO.getAllAddresses();
assertEquals(1, addresses.size());
assertEquals("Rua fulano", addresses.get(0).getStreet());
assertEquals("123/A", addresses.get(0).getNumber());
}
Code language: PHP (php)
Agora, se tivermos o teste a seguir, o objeto criado é desperdiçado:
@Test
public void testGetNoAddress() {
List<Address> addresses = addressDAO.getAllAddresses();
assertEquals(0, addresses.size());
}
Code language: PHP (php)
Se o código for como o seguinte, teremos redundância de código. também temos de decidir SE o outro objeto deve ser criado no @Before
também ou no método.
@Test
public void testGetAllAddressesMoreThanOne() {
addressDAO.addAddress(address);
Address address2 = new Address();
address2.setStreet("Outra rua");
address2.setNumber("111");
addressDAO.addAddress(address2);
List<Address> addresses = addressDAO.getAllAddresses();
assertEquals(1, addresses.size());
assertEquals("Rua fulano", addresses.get(0).getStreet());
assertEquals("123/A", addresses.get(0).getNumber());
}
Code language: PHP (php)
Esses inconvenientes são menores quando comparados à tarefa de criar uma rede de dependências. Por exemplo, para testar uma classe Person
que agrega um Address
em um outro caso de teste, teremos de ter um @Before
semelhante a esse:
private Person person;
private Address address;
private PersonDAO personDAO;
@Before
public void setUp() {
address = new Address();
address.setStreet("Rua fulano");
address.setNumber("123/A");
person = new Person();
person.setName("João");
person.setAddress(address);
personDAO = new PersonDAO();
}
Code language: PHP (php)
O código para a criação de endereços foi duplicado, e é difícil criar as dependências. Nesses exemplos, vemos casos simples, mas é fácil visualizar como a situação irá se complicar.
Nós solucionamos esse problema criando uma classe para criar esses objetos. Essa classe seria algo como isso:
public class TestUtil {
public static Address utilCreateAddress(String street, String number) {
Address address = new Address();
address.setStreet("Rua fulano");
address.setNumber("123/A");
return address;
}
public static Person utilCreatePerson(String name, Address address) {
Person person = new Person();
person.setName(name);
person.setAddress(address);
return person;
}
}
Code language: JavaScript (javascript)
Nossos casos de teste estendiam a TestUtil
, facilitando a criação de objetos:
public class TestAddress2 extends TestUtil {
private AddressDAO addressDAO = new AddressDAO();
@Test
public void testGetAllAddresses() {
Address address = utilCreateAddress("Rua fulano", "123/A");
addressDAO.addAddress(address);
List<Address> addresses = addressDAO.getAllAddresses();
assertEquals(1, addresses.size());
assertEquals("Rua fulano", addresses.get(0).getStreet());
assertEquals("123/A", addresses.get(0).getNumber());
}
@Test
public void testGetNoAddress() {
List<Address> addresses = addressDAO.getAllAddresses();
assertEquals(0, addresses.size());
}
@Test
public void testGetAllAddressesMoreThanOne() {
Address address = utilCreateAddress("Rua fulano", "123/A");
Address address2 = utilCreateAddress("Outra rua", "111");
addressDAO.addAddress(address);
addressDAO.addAddress(address2);
List<Address> addresses = addressDAO.getAllAddresses();
assertEquals(2, addresses.size());
assertEquals("Rua fulano", addresses.get(0).getStreet());
assertEquals("123/A", addresses.get(0).getNumber());
}
}
Code language: PHP (php)
Como também precisávamos frequentemente de um objeto qualquer, ou que apenas um ou outro parâmetro fosse definido, criávamos variantes dos métodos:
public static Address utilCreateAddress() {
return utilCreateAddress("Qualquer", "Qualquer");
}
public static Person utilCreatePerson() {
return utilCreatePerson("José", utilCreateAddress());
}
Code language: PHP (php)
O E-Plamtax foi um projeto um tanto complexo, com grandes redes de dependências de objetos. O uso desses utilitários de teste viabilizou a prática de TDD no sistema. Era emocionante descobrir que, para criar aquele documento que dependia de sete outros documentos e uns cinco ou seis usuários, bastava chamar um método.
Naturalmente, há mais sobre nossos utilitários de teste do que foi escrito aqui, e pode haver mais ainda que sequer fizemos. (Por exemplo, pode ser interessante produzir utilitários de teste para classes específicas, ao invés de um gigantesco utilitário) Entretanto, como a ideia é bem simples, esperamos que esse pontapé inicial lhe motive a pensar sobre o tema. Até mais!
Post Revisions:
- October 29, 2023 @ 19:15:35 [Current Revision] by brandizzi
- October 29, 2023 @ 19:15:35 by brandizzi
- October 26, 2023 @ 10:05:40 by brandizzi
- October 26, 2023 @ 10:04:43 by brandizzi
Changes:
October 26, 2023 @ 10:04:43 | Current Revision | ||
---|---|---|---|
Title | |||
Deleted: Substituindo | Added: Substituindo métodos de set-up por utilitários de teste |
Content | |||
---|---|---|---|
Unchanged: <!-- wp:paragraph --> | Unchanged: <!-- wp:paragraph --> | ||
Unchanged: <p><em>(Este é um post que publiquei no <a href="https:/ /web.archive.org/ web/20100806130712/ http://blog.seatecnologia.com.br: 80/2010/05/20/ utilitirios- de-teste">antigo blog da SEA Tecnologia</a>. Como ainda é relevante, resolvi republicá-lo.)</em></p> | Unchanged: <p><em>(Este é um post que publiquei no <a href="https:/ /web.archive.org/ web/20100806130712/ http://blog.seatecnologia.com.br: 80/2010/05/20/ utilitirios- de-teste">antigo blog da SEA Tecnologia</a>. Como ainda é relevante, resolvi republicá-lo.)</em></p> | ||
Unchanged: <!-- /wp:paragraph --> | Unchanged: <!-- /wp:paragraph --> | ||
Unchanged: <!-- wp:paragraph --> | Unchanged: <!-- wp:paragraph --> | ||
Deleted: <p> | Added: <p>Uma das muitas aprendizagens que adquiri na antiga SEA Tecnologia é a criação de <em>utilitários de teste</em>.</p> | ||
Unchanged: <!-- /wp:paragraph --> | Unchanged: <!-- /wp:paragraph --> | ||
Unchanged: <!-- wp:paragraph --> | Unchanged: <!-- wp:paragraph --> | ||
Unchanged: <p>Utilitários de teste são uma maneira de reaproveitar código em testes unitários. Usualmente, isso é feito utilizando os métodos <code>setUp</code> ou <code>@Before</code> dos casos de teste, mas isso tem algumas desvantagens. Por exemplo, em um caso de teste, podemos ter a seguinte inicialização:</p> | Unchanged: <p>Utilitários de teste são uma maneira de reaproveitar código em testes unitários. Usualmente, isso é feito utilizando os métodos <code>setUp</code> ou <code>@Before</code> dos casos de teste, mas isso tem algumas desvantagens. Por exemplo, em um caso de teste, podemos ter a seguinte inicialização:</p> | ||
Unchanged: <!-- /wp:paragraph --> | Unchanged: <!-- /wp:paragraph --> | ||
Unchanged: <!-- wp:code --> | Unchanged: <!-- wp:code --> | ||
Unchanged: <pre class="wp-block- code"><code>private Address address; | Unchanged: <pre class="wp-block- code"><code>private Address address; | ||
Unchanged: private AddressDAO addressDAO; | Unchanged: private AddressDAO addressDAO; | ||
Unchanged: @Before | Unchanged: @Before | ||
Unchanged: public void setUp() { | Unchanged: public void setUp() { | ||
Unchanged: address = new Address(); | Unchanged: address = new Address(); | ||
Unchanged: address.setStreet("Rua fulano"); | Unchanged: address.setStreet("Rua fulano"); | ||
Unchanged: address.setNumber("123/A"); | Unchanged: address.setNumber("123/A"); | ||
Unchanged: addressDAO = new AddressDAO(); | Unchanged: addressDAO = new AddressDAO(); | ||
Unchanged: }</code></pre> | Unchanged: }</code></pre> | ||
Unchanged: <!-- /wp:code --> | Unchanged: <!-- /wp:code --> | ||
Unchanged: <!-- wp:paragraph --> | Unchanged: <!-- wp:paragraph --> | ||
Unchanged: <p>Essa inicialização funciona bem no teste abaixo...</p> | Unchanged: <p>Essa inicialização funciona bem no teste abaixo...</p> | ||
Unchanged: <!-- /wp:paragraph --> | Unchanged: <!-- /wp:paragraph --> | ||
Unchanged: <!-- wp:code --> | Unchanged: <!-- wp:code --> | ||
Unchanged: <pre class="wp-block- code"><code>@Test | Unchanged: <pre class="wp-block- code"><code>@Test | ||
Unchanged: public void testGetAllAddresses(){ | Unchanged: public void testGetAllAddresses(){ | ||
Unchanged: addressDAO.addAddress(address); | Unchanged: addressDAO.addAddress(address); | ||
Unchanged: List<Address> addresses = addressDAO.getAllAddresses(); | Unchanged: List<Address> addresses = addressDAO.getAllAddresses(); | ||
Unchanged: assertEquals(1, addresses.size()); | Unchanged: assertEquals(1, addresses.size()); | ||
Unchanged: assertEquals("Rua fulano", addresses.get( 0).getStreet()); | Unchanged: assertEquals("Rua fulano", addresses.get( 0).getStreet()); | ||
Unchanged: assertEquals("123/A", addresses.get( 0).getNumber()); | Unchanged: assertEquals("123/A", addresses.get( 0).getNumber()); | ||
Unchanged: } </code></pre> | Unchanged: } </code></pre> | ||
Unchanged: <!-- /wp:code --> | Unchanged: <!-- /wp:code --> | ||
Unchanged: <!-- wp:paragraph --> | Unchanged: <!-- wp:paragraph --> | ||
Unchanged: <p>Agora, se tivermos o teste a seguir, o objeto criado é desperdiçado:</p> | Unchanged: <p>Agora, se tivermos o teste a seguir, o objeto criado é desperdiçado:</p> | ||
Unchanged: <!-- /wp:paragraph --> | Unchanged: <!-- /wp:paragraph --> | ||
Unchanged: <!-- wp:code --> | Unchanged: <!-- wp:code --> | ||
Unchanged: <pre class="wp-block- code"><code>@Test | Unchanged: <pre class="wp-block- code"><code>@Test | ||
Unchanged: public void testGetNoAddress() { | Unchanged: public void testGetNoAddress() { | ||
Unchanged: List<Address> addresses = addressDAO.getAllAddresses(); | Unchanged: List<Address> addresses = addressDAO.getAllAddresses(); | ||
Unchanged: assertEquals(0, addresses.size()); | Unchanged: assertEquals(0, addresses.size()); | ||
Unchanged: }</code></pre> | Unchanged: }</code></pre> | ||
Unchanged: <!-- /wp:code --> | Unchanged: <!-- /wp:code --> | ||
Unchanged: <!-- wp:paragraph --> | Unchanged: <!-- wp:paragraph --> | ||
Unchanged: <p>Se o código for como o seguinte, teremos redundância de código. também temos de decidir SE o outro objeto deve ser criado no <code>@Before</code> também ou no método.</p> | Unchanged: <p>Se o código for como o seguinte, teremos redundância de código. também temos de decidir SE o outro objeto deve ser criado no <code>@Before</code> também ou no método.</p> | ||
Unchanged: <!-- /wp:paragraph --> | Unchanged: <!-- /wp:paragraph --> | ||
Unchanged: <!-- wp:code --> | Unchanged: <!-- wp:code --> | ||
Unchanged: <pre class="wp-block- code"><code>@Test | Unchanged: <pre class="wp-block- code"><code>@Test | ||
Unchanged: public void testGetAllAddressesMoreThanOne() { | Unchanged: public void testGetAllAddressesMoreThanOne() { | ||
Unchanged: addressDAO.addAddress(address); | Unchanged: addressDAO.addAddress(address); | ||
Unchanged: Address address2 = new Address(); | Unchanged: Address address2 = new Address(); | ||
Unchanged: address2.setStreet("Outra rua"); | Unchanged: address2.setStreet("Outra rua"); | ||
Unchanged: address2.setNumber("111"); | Unchanged: address2.setNumber("111"); | ||
Unchanged: addressDAO.addAddress(address2); | Unchanged: addressDAO.addAddress(address2); | ||
Unchanged: List<Address> addresses = addressDAO.getAllAddresses(); | Unchanged: List<Address> addresses = addressDAO.getAllAddresses(); | ||
Unchanged: assertEquals(1, addresses.size()); | Unchanged: assertEquals(1, addresses.size()); | ||
Unchanged: assertEquals("Rua fulano", addresses.get( 0).getStreet()); | Unchanged: assertEquals("Rua fulano", addresses.get( 0).getStreet()); | ||
Unchanged: assertEquals("123/A", addresses.get( 0).getNumber()); | Unchanged: assertEquals("123/A", addresses.get( 0).getNumber()); | ||
Unchanged: }</code></pre> | Unchanged: }</code></pre> | ||
Unchanged: <!-- /wp:code --> | Unchanged: <!-- /wp:code --> | ||
Unchanged: <!-- wp:paragraph --> | Unchanged: <!-- wp:paragraph --> | ||
Unchanged: <p>Esses inconvenientes são menores quando comparados à tarefa de criar uma rede de dependências. Por exemplo, para testar uma classe <code>Person</code> que agrega um <code>Address</code> em um outro caso de teste, teremos de ter um <code>@Before</code> semelhante a esse:</p> | Unchanged: <p>Esses inconvenientes são menores quando comparados à tarefa de criar uma rede de dependências. Por exemplo, para testar uma classe <code>Person</code> que agrega um <code>Address</code> em um outro caso de teste, teremos de ter um <code>@Before</code> semelhante a esse:</p> | ||
Unchanged: <!-- /wp:paragraph --> | Unchanged: <!-- /wp:paragraph --> | ||
Unchanged: <!-- wp:code --> | Unchanged: <!-- wp:code --> | ||
Unchanged: <pre class="wp-block- code"><code>private Person person; | Unchanged: <pre class="wp-block- code"><code>private Person person; | ||
Unchanged: private Address address; | Unchanged: private Address address; | ||
Unchanged: private PersonDAO personDAO; | Unchanged: private PersonDAO personDAO; | ||
Unchanged: @Before | Unchanged: @Before | ||
Unchanged: public void setUp() { | Unchanged: public void setUp() { | ||
Unchanged: address = new Address(); | Unchanged: address = new Address(); | ||
Unchanged: address.setStreet("Rua fulano"); | Unchanged: address.setStreet("Rua fulano"); | ||
Unchanged: address.setNumber("123/A"); | Unchanged: address.setNumber("123/A"); | ||
Unchanged: person = new Person(); | Unchanged: person = new Person(); | ||
Unchanged: person.setName("João"); | Unchanged: person.setName("João"); | ||
Unchanged: person.setAddress(address); | Unchanged: person.setAddress(address); | ||
Unchanged: personDAO = new PersonDAO(); | Unchanged: personDAO = new PersonDAO(); | ||
Unchanged: } </code></pre> | Unchanged: } </code></pre> | ||
Unchanged: <!-- /wp:code --> | Unchanged: <!-- /wp:code --> | ||
Unchanged: <!-- wp:paragraph --> | Unchanged: <!-- wp:paragraph --> | ||
Unchanged: <p>O código para a criação de endereços foi duplicado, e é difícil criar as dependências. Nesses exemplos, vemos casos simples, mas é fácil visualizar como a situação irá se complicar.</p> | Unchanged: <p>O código para a criação de endereços foi duplicado, e é difícil criar as dependências. Nesses exemplos, vemos casos simples, mas é fácil visualizar como a situação irá se complicar.</p> | ||
Unchanged: <!-- /wp:paragraph --> | Unchanged: <!-- /wp:paragraph --> | ||
Unchanged: <!-- wp:paragraph --> | Unchanged: <!-- wp:paragraph --> | ||
Unchanged: <p>Nós solucionamos esse problema criando uma classe para criar esses objetos. Essa classe seria algo como isso:</p> | Unchanged: <p>Nós solucionamos esse problema criando uma classe para criar esses objetos. Essa classe seria algo como isso:</p> | ||
Unchanged: <!-- /wp:paragraph --> | Unchanged: <!-- /wp:paragraph --> | ||
Unchanged: <!-- wp:code --> | Unchanged: <!-- wp:code --> | ||
Unchanged: <pre class="wp-block- code"><code>public class TestUtil { | Unchanged: <pre class="wp-block- code"><code>public class TestUtil { | ||
Unchanged: public static Address utilCreateAddress(String street, String number) { | Unchanged: public static Address utilCreateAddress(String street, String number) { | ||
Unchanged: Address address = new Address(); | Unchanged: Address address = new Address(); | ||
Unchanged: address.setStreet("Rua fulano"); | Unchanged: address.setStreet("Rua fulano"); | ||
Unchanged: address.setNumber("123/A"); | Unchanged: address.setNumber("123/A"); | ||
Unchanged: return address; | Unchanged: return address; | ||
Unchanged: } | Unchanged: } | ||
Unchanged: public static Person utilCreatePerson(String name, Address address) { | Unchanged: public static Person utilCreatePerson(String name, Address address) { | ||
Unchanged: Person person = new Person(); | Unchanged: Person person = new Person(); | ||
Unchanged: person.setName(name); | Unchanged: person.setName(name); | ||
Unchanged: person.setAddress(address); | Unchanged: person.setAddress(address); | ||
Unchanged: return person; | Unchanged: return person; | ||
Unchanged: } | Unchanged: } | ||
Unchanged: }</code></pre> | Unchanged: }</code></pre> | ||
Unchanged: <!-- /wp:code --> | Unchanged: <!-- /wp:code --> | ||
Unchanged: <!-- wp:paragraph --> | Unchanged: <!-- wp:paragraph --> | ||
Unchanged: <p>Nossos casos de teste estendiam a <code>TestUtil</code>, facilitando a criação de objetos:</p> | Unchanged: <p>Nossos casos de teste estendiam a <code>TestUtil</code>, facilitando a criação de objetos:</p> | ||
Unchanged: <!-- /wp:paragraph --> | Unchanged: <!-- /wp:paragraph --> | ||
Unchanged: <!-- wp:code --> | Unchanged: <!-- wp:code --> | ||
Unchanged: <pre class="wp-block- code"><code>public class TestAddress2 extends TestUtil { | Unchanged: <pre class="wp-block- code"><code>public class TestAddress2 extends TestUtil { | ||
Unchanged: private AddressDAO addressDAO = new AddressDAO(); | Unchanged: private AddressDAO addressDAO = new AddressDAO(); | ||
Unchanged: @Test | Unchanged: @Test | ||
Unchanged: public void testGetAllAddresses() { | Unchanged: public void testGetAllAddresses() { | ||
Unchanged: Address address = utilCreateAddress("Rua fulano", "123/A"); | Unchanged: Address address = utilCreateAddress("Rua fulano", "123/A"); | ||
Unchanged: addressDAO.addAddress(address); | Unchanged: addressDAO.addAddress(address); | ||
Unchanged: List<Address> addresses = addressDAO.getAllAddresses(); | Unchanged: List<Address> addresses = addressDAO.getAllAddresses(); | ||
Unchanged: assertEquals(1, addresses.size()); | Unchanged: assertEquals(1, addresses.size()); | ||
Unchanged: assertEquals("Rua fulano", addresses.get( 0).getStreet()); | Unchanged: assertEquals("Rua fulano", addresses.get( 0).getStreet()); | ||
Unchanged: assertEquals("123/A", addresses.get( 0).getNumber()); | Unchanged: assertEquals("123/A", addresses.get( 0).getNumber()); | ||
Unchanged: } | Unchanged: } | ||
Unchanged: @Test | Unchanged: @Test | ||
Unchanged: public void testGetNoAddress() { | Unchanged: public void testGetNoAddress() { | ||
Unchanged: List<Address> addresses = addressDAO.getAllAddresses(); | Unchanged: List<Address> addresses = addressDAO.getAllAddresses(); | ||
Unchanged: assertEquals(0, addresses.size()); | Unchanged: assertEquals(0, addresses.size()); | ||
Unchanged: } | Unchanged: } | ||
Unchanged: @Test | Unchanged: @Test | ||
Unchanged: public void testGetAllAddressesMoreThanOne() { | Unchanged: public void testGetAllAddressesMoreThanOne() { | ||
Unchanged: Address address = utilCreateAddress("Rua fulano", "123/A"); | Unchanged: Address address = utilCreateAddress("Rua fulano", "123/A"); | ||
Unchanged: Address address2 = utilCreateAddress("Outra rua", "111"); | Unchanged: Address address2 = utilCreateAddress("Outra rua", "111"); | ||
Unchanged: addressDAO.addAddress(address); | Unchanged: addressDAO.addAddress(address); | ||
Unchanged: addressDAO.addAddress(address2); | Unchanged: addressDAO.addAddress(address2); | ||
Unchanged: List<Address> addresses = addressDAO.getAllAddresses(); | Unchanged: List<Address> addresses = addressDAO.getAllAddresses(); | ||
Unchanged: assertEquals(2, addresses.size()); | Unchanged: assertEquals(2, addresses.size()); | ||
Unchanged: assertEquals("Rua fulano", addresses.get( 0).getStreet()); | Unchanged: assertEquals("Rua fulano", addresses.get( 0).getStreet()); | ||
Unchanged: assertEquals("123/A", addresses.get( 0).getNumber()); | Unchanged: assertEquals("123/A", addresses.get( 0).getNumber()); | ||
Unchanged: } | Unchanged: } | ||
Unchanged: } </code></pre> | Unchanged: } </code></pre> | ||
Unchanged: <!-- /wp:code --> | Unchanged: <!-- /wp:code --> | ||
Unchanged: <!-- wp:paragraph --> | Unchanged: <!-- wp:paragraph --> | ||
Unchanged: <p>Como também precisávamos frequentemente de um objeto qualquer, ou que apenas um ou outro parâmetro fosse definido, criávamos variantes dos métodos:</p> | Unchanged: <p>Como também precisávamos frequentemente de um objeto qualquer, ou que apenas um ou outro parâmetro fosse definido, criávamos variantes dos métodos:</p> | ||
Unchanged: <!-- /wp:paragraph --> | Unchanged: <!-- /wp:paragraph --> | ||
Unchanged: <!-- wp:code --> | Unchanged: <!-- wp:code --> | ||
Unchanged: <pre class="wp-block- code"><code>public static Address utilCreateAddress() { | Unchanged: <pre class="wp-block- code"><code>public static Address utilCreateAddress() { | ||
Unchanged: return utilCreateAddress("Qualquer", "Qualquer"); | Unchanged: return utilCreateAddress("Qualquer", "Qualquer"); | ||
Unchanged: } | Unchanged: } | ||
Unchanged: public static Person utilCreatePerson() { | Unchanged: public static Person utilCreatePerson() { | ||
Unchanged: return utilCreatePerson("José", utilCreateAddress()); | Unchanged: return utilCreatePerson("José", utilCreateAddress()); | ||
Unchanged: } </code></pre> | Unchanged: } </code></pre> | ||
Unchanged: <!-- /wp:code --> | Unchanged: <!-- /wp:code --> | ||
Unchanged: <!-- wp:paragraph --> | Unchanged: <!-- wp:paragraph --> | ||
Deleted: <p> | Added: <p>Aprendemos isto em um projeto um tanto complexo, com grandes redes de dependências de objetos. O uso desses utilitários de teste viabilizou a prática de <a href="https:/ /web.archive.org/ web/20100806130712/ http://pt.wikipedia.org/wiki/ Test_Driven_Development">TDD</a> no sistema. Era emocionante descobrir que, para criar aquele documento que dependia de sete outros documentos e uns cinco ou seis usuários, bastava chamar um método.</p> | ||
Unchanged: <!-- /wp:paragraph --> | Unchanged: <!-- /wp:paragraph --> | ||
Unchanged: <!-- wp:paragraph --> | Unchanged: <!-- wp:paragraph --> | ||
Unchanged: <p>Naturalmente, há mais sobre nossos utilitários de teste do que foi escrito aqui, e pode haver mais ainda que sequer fizemos. (Por exemplo, pode ser interessante produzir utilitários de teste para classes específicas, ao invés de um gigantesco utilitário) Entretanto, como a ideia é bem simples, esperamos que esse pontapé inicial lhe motive a pensar sobre o tema. Até mais!</p> | Unchanged: <p>Naturalmente, há mais sobre nossos utilitários de teste do que foi escrito aqui, e pode haver mais ainda que sequer fizemos. (Por exemplo, pode ser interessante produzir utilitários de teste para classes específicas, ao invés de um gigantesco utilitário) Entretanto, como a ideia é bem simples, esperamos que esse pontapé inicial lhe motive a pensar sobre o tema. Até mais!</p> | ||
Unchanged: <!-- /wp:paragraph --> | Unchanged: <!-- /wp:paragraph --> |
Note: Spaces may be added to comparison text to allow better line wrapping.