Tag: unit test
Série CI: Executando unit tests Jenkins via Maven
Olá Pessoal,
No post de hoje veremos como executar os unit tests, após executarmos mvn compile. Vou considerar que você já tem o Jenkins instalado e um projeto configurado.
Lets go…
Starting…
Primeiro passo é ir em configure do projeto no Jenkins, pare o mouse em cima do projeto/job criado e escolha configure.
Em Build, configuramos para rodar mvn compile.
Mas e se você quiser também rodar os unit tests? Simples, basta adicionar mvn test
Clique no botão add build step escolha Invoke top-level Maven targets e deixe conforme a imagem a seguir:
Pronto, após o compile vamos executar os testes.
Um problema
Se você mandar construir uma build e todos os testes tiverem passando, você não tem problemas aparentemente, mas faça um teste falhar e mande construir. Certamente verá isso:
Ué, um teste falhou, mas o build foi dado como sucess. Esse é o problema e vamos resolver.
Solução
A solução é muito simples, apenas vamos dizer que as falhas na execução de qualquer unit tests não podem ser ignoradas, para isso precisamos atualizar o comando mvn test, deixando assim:
test -Dmaven.test.failure.ignore=false
Salve as alterações e rode uma nova build clicando em build now. E aguarde….
Resultado
É isso que esperamos:
Pronto. Agora sempre que um teste falhar a construção da build também vai falhar.
Vou ficando por aqui e espero que tenham gostado do post.
See ya!!
Utilizando o Selenium para testes Automatizado
Olá Pessoal,
No post de hoje vamos ver como usar o Selenium para criação de testes funcionais. A ideia é um teste simples para mostrar a potência do framework e daí cabe a cada um usar de forma que atenda as necessidades do projeto. Para o post vou usar a versão selenium-server-standalone-2.32.0.jar disponível http://docs.seleniumhq.org/
lets go…
Overview sobre o Selenium
Bem, se você usar o Google e pesquisar sobre “Selenium unit test” verá vários links para a definição, então não há motivos para repetir no post. Veja no famoso Wikipedia. Há um post que gosto bastante sobre o Selenium que está no blog da Caelum.
Em poucas palavras, nos permite realizar teste funcionais simulando ações que um usuário estaria fazendo.
Mas por que usar um framework para isso?
Há vários motivos para fazer isso de maneira automatizada, como por exemplo:
- – produtividade;
- – qualidade;
- – custo;
- – feedback.
Contratar um time de profissionais para fazer testes que você pode automatizar, além de custar caro, o tempo gasto é muito maior que de forma automatizada e isso é importante. Assim podemos contratar profissionais para realizar em pontos estratégicos onde não temos como testar de forma automatizada. Como toda e qualquer ferramenta sempre há uma limitação e ai que entra o fator o humano.
Colocando mão na massa
Vamos colocar a mão na massa e criar um projeto muito simples. Faremos um teste que terá como objetivo acessar uma determinada página na internet e fazer uma pesquisa. Se tudo ocorrer bem, o teste vai passar. Mas, por exemplo, se a página estiver indisponível ou o endereço informado para o teste for inválido o teste vai falhar.
- Crie um Java project e dê o nome que quiser;
- Adicione a biblioteca do Selenium ao classpath do projeto;
- Crie uma classe de teste, ou seja, Junit Class. No meu caso criei com o nome de HelloSeleniumTest.java
Vamos criar o nosso primeiro teste que vai acessar a página do Google e pesquisar por “Camilo Lopes”. Veja o código a seguir.
public class HelloSeleniumTest {
@Before
public void setUp() throws Exception {
}
@Test
public void testSearchInGooglePage() {
WebDriver driver = new FirefoxDriver();
// Digo qual url para acessar
driver.get(“http://www.google.com”);
// Agora vamos buscar o elemento na página
WebElement inputTextGoogle = driver.findElement(By.name(“q”));
inputTextGoogle.sendKeys(“Camilo Lopes”);
/* faz um submit na página
* poderia buscar o botão search e fazer o submit tb.
*/
inputTextGoogle.submit();
assertTrue(driver.getPageSource().contains(driver.findElement(By.id(“gbqfq”)).getText()));
}
}
Entendendo o código
Apesar de que em alguns trechos eu coloquei comentários somente para facilitar o entendimento, vou explicar alguns pontos que considero importantes.
WebDriver: é uma interface do Selenium que todo Web Browser Drivers implementa. O Firefox Browser tem sua implementação, assim como IE e Chrome, cada um com sua particularidade, e é preciso dar uma olhada na documentação sobre como implementar.
Depois que instanciamos o driver, dizemos a URL que queremos testar (nesse caso será do Google), mas em um projeto JEE, por exemplo, vamos colocar o caminho onde está nossa aplicação.
Em seguida pesquisamos pelos elementos na página, para isso no Chrome podemos usar o atalho F12, clica na lupa que fica no rodapé e clica sobre o input text e ver qual o nome daquele campo. Podemos usar o id, nome etc. Veja:
Depois que fizemos isso, criamos uma variável para representar esse campo :
WebElement inputTextGoogle = driver.findElement(By.name(“q”));
E em seguida invocamos o método sendKeys(…) e passamos o valor que queremos que seja digitado no input. Para descobrir e conhecer melhor os métodos disponíveis tem que passar por alguns minutos vendo o que temos na documentação do framework.
inputTextGoogle.sendKeys(“Camilo Lopes”);
Logo em seguida fizemos o submit página
inputTextGoogle.submit();
Criando o assert
Bem, para que seja testado precisamos usar algum assertXXX do framework Junit. Então vamos verificar se após ter feito o submit há um elemento com o id informado na página.
O teste passa. Na verdade esse teste não tem nada de inteligente. Se você reparar, ele verifica se o input que pesquisamos na primeira página do Google é o mesmo na página do resultado da busca.
Claro que em nossa aplicação íamos testar algo mais voltado para regras de negócio. E o método getPageSource() nos ajuda nisso, em busca de um elemento na página corrente.
Execute o teste
Vamos executar os testes e aguardar por alguns segundos e veremos que o Selenium vai abrir o browser que definimos (no caso do post foi o Firefox) e realizar a pesquisa.
Convertendo isso para uma aplicação
Em uma aplicação web, vamos ter que usar a url onde nossa aplicação está rodando. Claro que vamos evitar que o endereço seja informado dentro da classe Java, este pode ser informado de um arquivo .properties por exemplo, efaremos assert voltado para as regras de negócio.
Conclusão
O objetivo desse post não era explorar como escrever bons testes com o Selenium, a ideia era apresentar o framework e vê-lo em ação. Após isso podemos tirar nossas próprias conclusões sobre a eficiência e produtividade gerada quando usamos corretamente. Já passei por algumas empresas e projetos onde falaram que o Selenium foi o responsável pelo aumento do dos prazos nas entregas. Acredito que o problema certamente não foi com o Selenium, mas sim na forma de como este foi usado ou adotado dentro do projeto.
E você tem usado o Selenium em seus projetos? Compartilhe sua experiência…
Abraços, see ya!!!
Série Spring: CRUD Spring 3 + Hibernate + Unit Tests
Olá Pessoal,
No post de hoje veremos como fazer um simples CRUD usando o Spring, integrando com Hibernate e testando via unit tests com JUNIT4. No último posts vimos apenas uma integração com o Hibernate e também um CRUD usando HibernateTemplate, esse aqui veremos que na versão 3 do Spring não precisamos mais do HiberanteTemplate e vamos testar nosso código com unit test.
Lets go…
Starting…
Primeiro passo é que estarei assumindo que você já tem .jars necessário para o ambiente. Já que esse não é o primeiro post da série, caso contrário terá que baixar os .jars para: driver Mysql 5, Hibernate 3.6, AOP, AspectJ, Spring 3.x.
Antes de começarmos a desenvolver, vamos primeiro estruturar nosso projeto e packages conforme a imagem a seguir:
Nosso CRUD será o cadastro de veículos que serão alugados. Claro que há muito mais regras de negócios do que a que veremos no exemplo a seguir, porém o nosso objetivo é explorar o framework Spring e não tratar todas as regras de negócio em um post.
- Crie a estrutura conforme a imagem acima
- Crie o arquivo de configuração de Spring, o qual chamei de springconfiguration.xml, e coloque dentro do package config.
- Agora vamos colocar a carne no nosso XML
Cabeçalho fica assim:
<beans xmlns=“http://www.springframework.org/schema/beans”
xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance”
xmlns:context=“http://www.springframework.org/schema/context”
xmlns:tx=“http://www.springframework.org/schema/tx”
xmlns:aop=“http://www.springframework.org/schema/aop”
xsi:schemaLocation=“http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd”>
Estarei comentando mais na frente ou in line apenas o que ainda não foi abordado nos posts anteriores.
O cara que busca os beans:
<context:component-scan base-package=“*”/>
Colocando translation
<!– esse cara faz as traduções das exception checked para as unchecked do Spring –>
<bean class=“org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor”/>
Data source
<!– pelo nome já diz, data source para conexão com o DB –>
<bean id=“dataSource” class=“org.springframework.jdbc.datasource.DriverManagerDataSource”>
<property name=“driverClassName” value=“com.mysql.jdbc.Driver”/>
<property name=“url” value=“jdbc:mysql://localhost/test”/>
<property name=“username” value=“root”/>
<property name=“password” value=“camilo2593”/>
</bean>
Configurando a SessionFactory
<!– Aqui estamos definido como será a parte de persistêcia, e dizemos que faremos via annotation –>
<bean id=“sessionFactory” class=“org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean”>
<!– informando a quem estaremos conectado –>
<property name=“dataSource” ref=“dataSource”/>
<!– dizendo onde estão as classes dominio, ele saberá devido anotação @Entity –>
<property name=“packagesToScan” value=“br.com.camilolopes.rentcar.domain.bean”/>
<!– configurando coisas especificas do Hibernate –>
<property name=“hibernateProperties”>
<props>
<prop key=“hibernate.dialect”>org.hibernate.dialect.MySQL5InnoDBDialect</prop>
<prop key=“hibernate.hbm2ddl.auto”>update</prop>
</props>
</property>
</bean>
Definindo Transaction
<!– definindo quem vai gerenciar as transaction, ou seja, será o Hibernate –>
<bean id=“transactionManager” class=“org.springframework.orm.hibernate3.HibernateTransactionManager”>
<property name=“sessionFactory” ref=“sessionFactory”/>
</bean>
</beans>
Há duas formas de declararmos as transaction no Spring por XML ou Annotation. Veremos as duas formas, no nosso caso de usarmos o XML faremos com AOP e você entenderá o motivo:
Via XML
<!– todo medoto que começa com add é required uma transaction –>
<tx:advice id=“txAdvice”>
<tx:attributes>
<tx:method name=“add*” propagation=“REQUIRED”/>
<tx:method name=“update*” propagation=“REQUIRED”/>
<tx:method name=“*” propagation=“SUPPORTS” read-only=“true”/>
</tx:attributes>
</tx:advice>
<!– toda classe que extends a interface terá uma referência para o advisor –>
<aop:config>
<aop:advisor pointcut = “execution(* *..RentCar.*(..)))” advice-ref=“txAdvice”/>
</aop:config>
Em alguns contexto dessa forma é bem mais prático que usar Annotations.
Via annotation
Remove todo o código XML acima e apenas adiciona a seguinte linha:
<tx:annotation-driven/>
Claro que teremos que anotar nas classes/métodos como @Transaction e informar como esse deve se comportar , seguindo o exemplo do XML acima seria algo assim:
@Transactional(readOnly=true,propagation=Propagation.SUPPORTS)
public class myClass{ }
Normalmente você colocaria isso na camada de serviço.Mas, se você está brincando e não tem uma camada de serviço, pode colocar direto no DAO.
E o método que faria uma das operações de banco ficaria assim:
@Transactional(isolation=Isolation.DEFAULT,propagation=Propagation.REQUIRED)
public void save(Car car) {
getCurrentSession().save(car);}
No nosso exemplo vamos não vamos usar Annotations e exploraremos o benefício de usar a versão do XML conforme acima, se vc deixar a tag para annotation no arquivo de configuração o Spring não vai se importar com isso.
Desenvolvimento
Após toda essa configuração, vamos agora desenvolver nossas classes .java. Começando pela classe de domínio:
@Entity
@Table(name=”CARS”)
public class Car implements Serializable{
private static final long serialVersionUID = -2896368465389020843L;
@Id
@GeneratedValue
private Long id;
private String manufacter;
private String description;
private BigDecimal marketValue;
//getters/setters omitidos
Basicamente isso .
Interface DAO
public interface RentCarDAO {
void save(Car car);
List<Car> findAll();
List<Car> findAllByDescription(String description);
void update(Car car);
void delete();
}
Implementação da Interface:
@Repository
public class RentCarDAOImpl implements RentCarDAO {
@Autowired
private SessionFactory sessionFactory;
public Session getCurrentSession(){
return sessionFactory.getCurrentSession();
}
@Override
public void save(Car car) {
getCurrentSession().save(car);
}
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
@Override
public List<Car> findAll() {
return getCurrentSession().createCriteria(Car.class).list();
}
@Override
public List<Car> findAllByDescription(String description) {
Criteria createCriteria = getCurrentSession().createCriteria(Car.class);
createCriteria.add(Restrictions.ilike(“description”, description));
return (List<Car>) createCriteria.list();
}
@Override
public void update(Car car) {
getCurrentSession().update(car);
}
@Override
public void delete() {
Query query = getCurrentSession().createQuery(“delete from Car where id >0”);
query.executeUpdate();
}
Interface de Serviço
@Service
public interface RentCar {
void addNewCar(Car car);
List<Car> findAll();
List<Car> findCarByDescription(String description);
void updateCar(Car car);
void delete();
}
Classe que implementa o Serviço
@Service
public class RentCarServiceImpl implements RentCar {
@Autowired
private RentCarDAO rentCarDAO;
@Override
public void addNewCar(Car car) {
rentCarDAO.save(car);
}
public void setRentCarDAO(RentCarDAO rentCarDAO) {
this.rentCarDAO = rentCarDAO;
}
@Override
public List<Car> findAll() {
return rentCarDAO.findAll();
}
@Override
public List<Car>findCarByDescription(String description) {
return (List<Car>) rentCarDAO.findAllByDescription(description);
}
@Override
public void updateCar(Car car) {
rentCarDAO.update(car);
}
@Override
public void delete() {
rentCarDAO.delete();
}
}
Unit Test
Se não reparou quando criou o projeto, temos um source apenas para os unit tests, conforme a imagem a seguir:
Agora crie a classe de teste. A seguir mostrarei apenas dois simples testes, você deve criar os demais para validar os cenários, não coloquei todos para não ficar mais longo ainda o post.
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={“classpath:config/springconfiguration.xml”})
public class RentCarServicesTest {
@Autowired
private RentCar rentCarServicesImpl;
private Car car;
@Before
public void setUp() throws Exception {
car = new Car();
}
@Test
public void testAddingNewCarWithSuccess(){
try{
car.setDescription(“Civic”);
car.setManufacter(“Honda”);
car.setMarketValue(new BigDecimal(740000));
rentCarServicesImpl.addNewCar(car );
}catch (Exception e) {
Assert.fail(“not expected result”);
}
}
@Test
public void testListAllCarIsNotEmpty(){
assertFalse(rentCarServicesImpl.findAll().isEmpty());
}
Resultado
Lembre-se que seu BD precisa está rodando
Ufa! Esse post foi longo heim, mas não tinha outra forma de mostrar tudo se não fosse assim, e olha que busquei resumir ao máximo possível. Enfim, vou ficando por aqui.
GitHub
Acesse o repositório no github com todos os projetos da série Spring: https://github.com/camilolopes/workspacespring
Espero que tenham gostado do post.
Abraços, see ya!!
Série Spring:Rodando Unit Test com Spring Framework
Olá Pessoal,
Nesse post veremos como rodar nossos unit tests com o Spring framework, ou seja, aproveitar tudo de bom que tem o Spring e fazer nossos unit test funcionar normalmente. É bastante simples.
lets go…
Começando
Bem não vou entrar nos detalhes do que é unit test, Spring, JUnit etc. Vamos direto ao ponto de maneira prática. Primeiro Crie um Java Project, o meu será SpringExampleUnitTest
note: claro que você precisa ter baixado o Spring framework core versão 3.x.
Note: adicione o arquivo commons-logging-1.1.1.jar caso não tenha só baixar esse arquivo, basta digitar o nome no Google .
Desenvolvendo
Como bom baiano e pensando no carnaval de salvador vamos de chicletão. Temos uma interface que tem um método e uma classe que vai implementar:
package br.com.camilolopes;
public interface Competidor {
public void apresentar();
}
public class Chicletao implements Competidor {
private Chicleteiro chicleteiroMusica;
@Override
public void apresentar() {
chicleteiroMusica.cantar();
}
public void setChicleteiroMusica(Chicleteiro chicleteiroMusica) {
this.chicleteiroMusica = chicleteiroMusica;
}
}
public interface Musica {
void cantar();
}
public class Chicleteiro implements Musica {
@Override
public void cantar() {
System.out.println(“chicleteiro eu, chicleteira ela”);
}
}
E no package conf, criamos um xml com as configurações do Spring:
<beans xmlns=”http://www.springframework.org/schema/beans”
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
xsi:schemaLocation=”http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd”>
<!– classe normal –>
<bean id=”chicleteiro” />
<!– classe que implementa a interface –>
<bean id=”bell”>
<property name=”chicleteiroMusica” ref=”chicleteiro”/>
</bean>
</beans>
Pronto. Agora vamos criar a classe de teste.Porém, vamos entender o que acontece com a nossa aplicação. Quando o método apresentar() é invocado, a classe vai se apresentar com a musica que deseja, no caso da classe Chicleteiro, vai cantar: “chicleteiro eu, chicleteira ela”.
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={“classpath:conf/idolos.xml”})
public class ChicletaoTest {
@Autowired
private Chicleteiro chicleteiro;
@Test
public void testCantar() {
Chicletao chicletao = new Chicletao();
chicletao.setChicleteiroMusica(chicleteiro);
try{
chicletao.apresentar();
}catch (NullPointerException e) {
Assert.fail(“not expected result”);
}
}
Com Spring precisamos usar anotação @RunWith e informar qual framework vamos usar, no nosso caso usamos o JUNIT.Em seguida com anotações @ContextConfiguration estamos dizendo qual o xml que tem as configurações do Spring que usaremos para os testes. Que é o mesmo da aplicação. Em seguida fizemos um teste que apenas chama o método apresentar, e esperamos que nunca tenhamos um NullPointerException, mas para isso acontecer é apenas se a instância que chama o método for null, ou seja, não for instanciada. E com esse teste estamos validando duas coisas, uma que o Spring realmente está instanciando o atributo e que o resultado é o que esperamos. Veja:
E assim temos nosso unit test integrado com o Spring. Simples não?
GitHub
Acesse o repositório no github com todos os projetos da série Spring: https://github.com/camilolopes/workspacespring
Vou ficando por aqui!!
See ya!