Recentemente, passamos por um problemão aqui com as nossas aplicações.
Houve uma mudança na arquitetura e falhamente não efetuamos testes de stress antes de subir a versão. É obvio que assim que o site começou a ter muitos acessos ele começou a cair. Resultado: tivemos que fazer rollback de tudo, e como foi uma mudança de arquitetura isso implicou em substituição de servidores, que embora sejam virtualizados, ainda não é rapida assim a sua substuição, deixando o site por algumas horas fora.
Isso gerou um grande stress para o negócio e sabemos claramente que houveram falhas tanto na área de dev como na área de infra.
O importante é o que aprendemos com erros e o que fazemos para que eles não se repitam.
Nesse caso fizemos um acerto com a infra, e ao invés de fazer várias mudanças na arquitetura fizemos apenas uma das alterações e aplicamos a versão para minimizar os locais de erro.
Após estudamos uma estratégia de testes de stress e junto com a equipe de Web Analitcs verificamos qual seria a quantidade de acessos simultâneos para testar a estabilidade.
Como responsável pelos testes preparei scripts no Jmetter para testar isso, e após scripts e usuários configurados no Jmetter colocamos a rodar. Resultado: derrubamos os sites(em homologação é claro). Após vários ajustes de arquitetura, conseguimos estabilizar o ambiente e só com uma grande quantidade de acessos é que derrubamos o site, quantidade essa que não se replica em número de acessos em produção.
Se você está pensando em verificar a estabilidade do seu software vamos as seguintes dicas:
1) Conheça bem a arquitetura do seu sistema, isso vai ajudar muito a você determinar o quanto seu teste é válido. Por exemplo aqui nós temos balanceamento e um stick, ou seja sempre que eu realizava testes com o Jmetter na minha máquina estava sobrecarregando somente um dos servers, pois quando eu caia no balancer ele reconhecia meu IP e me mandava sempre para o mesmo server. Para resolver isso forçamos junto com a infra que a minha máquina caisse em um servidor e a máquina de outro colega caisse em outro server, e dividimos as conexões.
2) Se você não é o gerenciador do ambiente, mantenha contato com eles para juntos avaliarem a melhor forma de stressar seu ambiente.
3) Escolha a ferramenta certa para testar seu software.
4) Estude a ferramente e como você irá conseguir tirar melhor proveito dela para seu teste.
5) Não esqueça de incluir este tempo na sua preparação do teste e que para que esse teste tenha sucesso, você deve garantir que os outros atributos de qualidade sejam garantidos:
* Seu software precisa estar funcional!
* Seu software precisa ser confiavel!
* Seu software precisa ser usável!
* Seu software precisa ser eficaz!
* Seu software precisa ser manutenivel!
* Seu software precisa ser portável!
6) Use os principios da agilidade e sempre entregue valor ao seu cliente!
Quer saber mais sobre Jmetter? Acompanhe meu próximo post.
Mostrando postagens com marcador Testes funcionais. Mostrar todas as postagens
Mostrando postagens com marcador Testes funcionais. Mostrar todas as postagens
quarta-feira, 10 de abril de 2013
quinta-feira, 7 de fevereiro de 2013
Continuação Dojo
Em continuação ao último post, hoje pretendo explicar o código de teste funcional que criei e se adequava ao desafio.
Em primeiro lugar se você pensa em escrever um código de teste legal aprenda o conceito de page objects. Isso ajudará você a economizar muitas linhas de código e facilitará a manutenção dos mesmos.
Iniciei a codificação mapeando os elementos da minha página em um objeto e criando métodos para que a minha classe de teste pudesse acessa-los. Os primeiros objetos mapeados, foram todos os campos do formulário como combos, inputs, buttons, etc. Feito isso já tinha o básico para iniciar a classe de testes.
public class PaginaFormularioCadastro {
private WebDriver driver;
public PaginaFormularioCadastro(WebDriver driver) {
super();
this.driver = driver;
}
public void selecionaPessoaFisica(){
driver.findElement(By.id("legalEntity.F")).click();
}
public void selecionaPessoaJuridica(){
driver.findElement(By.id("legalEntity.J")).click();
}
public void escreveNome(String nome){
driver.findElement(By.id("firstName")).sendKeys(nome);
}
public void escreveUsuario(String usuario){
driver.findElement(By.id("userName")).sendKeys(usuario);
}
public void escreveSenha(String senha){
driver.findElement(By.id("password")).sendKeys(senha);
}
public void reEscreveSenha(String senha){
driver.findElement(By.id("password2")).sendKeys(senha);
}
public void escreveEmail(String email){
driver.findElement(By.id("email")).sendKeys(email);
}
public void queroInfoGrupo(){
driver.findElement(By.id("complement.rbsEmail")).click();
}
public void queroInfoParceirosGrupo(){
driver.findElement(By.id("complement.otherEmail")).click();
}
public void aceitaTermo(){
driver.findElement(By.id("acceptTerms")).click();
}
public void cadastrar(){
driver.findElement(By.cssSelector("input[type=\"submit\"]")).click();
}
}
Antes disso preparei uma classe que conteria as assinaturas @before e @after, que poderão serem usadas por outras classes de teste. Iniciei a classe de teste estendendo a classe que cotei acima.
public class Teste {
protected WebDriver driver;
protected String baseUrl;
private StringBuffer verificationErrors = new StringBuffer();
@Before
public void setUp() throws Exception {
driver = new FirefoxDriver();
baseUrl = "http://zerohora.clicrbs.com.br/wrs/action/update/newUser;jsessionid=ac19071f30d825732ff18c3a4149b3cfc47cf2a125ef.e34RbNaLchqQay0NbhmTc40.22?site=4446";
driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
driver.get(baseUrl);
}
@After
public void tearDown() throws Exception {
driver.quit();
String verificationErrorString = verificationErrors.toString();
if (!"".equals(verificationErrorString)) {
fail(verificationErrorString);
}
}
}
Comecei a chamar os métodos criados no objeto para fazer as simulações. Assim que essa etapa estava concluída e funcionando, precisava das assertivas para garantir que o teste passou, então implementei no objeto, métodos que faziam essas verificações.
Acabei os cenários de teste na minha classe e parti para verificar o funcionamentos. De cara eu sabia que teria problemas para atender aos critérios de aceite do teste devido a estar usando sempre o mesmo nome de usuário para cadastrar, mesmo assim executei o teste apenas modificando esse parâmetro e vi que o teste estava funcionando. Para resolver esse problema criei um objeto chamado usuário com o atributo username.
public class Usuario {
protected String username;
public Usuario(String username) {
super();
this.username = username.replaceAll("[ :]", "");
}
protected String getUsername() {
return username;
}
protected void setUsername(String username) {
this.username = username.replaceAll("[ :]", "");
}
}
O construtor desse atributo pegava a hora e data do sistema, retirava espaços em branco e barras e convertia para string. Cada vez que eu executava o teste ele pegava um timestamp diferente. Resolvido isso meu teste ficou pronto para ser executado várias vezes sem precisar de ajuste a cada execução.
Done? Done!
Em primeiro lugar se você pensa em escrever um código de teste legal aprenda o conceito de page objects. Isso ajudará você a economizar muitas linhas de código e facilitará a manutenção dos mesmos.
Iniciei a codificação mapeando os elementos da minha página em um objeto e criando métodos para que a minha classe de teste pudesse acessa-los. Os primeiros objetos mapeados, foram todos os campos do formulário como combos, inputs, buttons, etc. Feito isso já tinha o básico para iniciar a classe de testes.
public class PaginaFormularioCadastro {
private WebDriver driver;
public PaginaFormularioCadastro(WebDriver driver) {
super();
this.driver = driver;
}
public void selecionaPessoaFisica(){
driver.findElement(By.id("legalEntity.F")).click();
}
public void selecionaPessoaJuridica(){
driver.findElement(By.id("legalEntity.J")).click();
}
public void escreveNome(String nome){
driver.findElement(By.id("firstName")).sendKeys(nome);
}
public void escreveUsuario(String usuario){
driver.findElement(By.id("userName")).sendKeys(usuario);
}
public void escreveSenha(String senha){
driver.findElement(By.id("password")).sendKeys(senha);
}
public void reEscreveSenha(String senha){
driver.findElement(By.id("password2")).sendKeys(senha);
}
public void escreveEmail(String email){
driver.findElement(By.id("email")).sendKeys(email);
}
public void queroInfoGrupo(){
driver.findElement(By.id("complement.rbsEmail")).click();
}
public void queroInfoParceirosGrupo(){
driver.findElement(By.id("complement.otherEmail")).click();
}
public void aceitaTermo(){
driver.findElement(By.id("acceptTerms")).click();
}
public void cadastrar(){
driver.findElement(By.cssSelector("input[type=\"submit\"]")).click();
}
}
public class Teste {
protected WebDriver driver;
protected String baseUrl;
private StringBuffer verificationErrors = new StringBuffer();
@Before
public void setUp() throws Exception {
driver = new FirefoxDriver();
baseUrl = "http://zerohora.clicrbs.com.br/wrs/action/update/newUser;jsessionid=ac19071f30d825732ff18c3a4149b3cfc47cf2a125ef.e34RbNaLchqQay0NbhmTc40.22?site=4446";
driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
driver.get(baseUrl);
}
@After
public void tearDown() throws Exception {
driver.quit();
String verificationErrorString = verificationErrors.toString();
if (!"".equals(verificationErrorString)) {
fail(verificationErrorString);
}
}
}
Comecei a chamar os métodos criados no objeto para fazer as simulações. Assim que essa etapa estava concluída e funcionando, precisava das assertivas para garantir que o teste passou, então implementei no objeto, métodos que faziam essas verificações.
Acabei os cenários de teste na minha classe e parti para verificar o funcionamentos. De cara eu sabia que teria problemas para atender aos critérios de aceite do teste devido a estar usando sempre o mesmo nome de usuário para cadastrar, mesmo assim executei o teste apenas modificando esse parâmetro e vi que o teste estava funcionando. Para resolver esse problema criei um objeto chamado usuário com o atributo username.
public class Usuario {
protected String username;
public Usuario(String username) {
super();
this.username = username.replaceAll("[ :]", "");
}
protected String getUsername() {
return username;
}
protected void setUsername(String username) {
this.username = username.replaceAll("[ :]", "");
}
}
O construtor desse atributo pegava a hora e data do sistema, retirava espaços em branco e barras e convertia para string. Cada vez que eu executava o teste ele pegava um timestamp diferente. Resolvido isso meu teste ficou pronto para ser executado várias vezes sem precisar de ajuste a cada execução.
Done? Done!
sexta-feira, 25 de janeiro de 2013
Dojo de testes funcionais com Selenium
Olá pessoal! Essa semana foi bem movimentada e tenho bastante coisas para compartilhar com vocês, mas vou compartilhar aos poucos se não fico sem fôlego!
Bem a primeira experiência legal e que é o motivo desse post, trata-se de um primeiro dojo de testes funcionais usando Selenium que fizemos aqui na RBS.
No dojo reunimos testadores e desenvolvedores para que podessemos fazer uma troca legal.
O desafio era automatizar três cenários bem simples em uma ferramenta que é de uso de todo o time.
Infelizmente não foi possível acabar o desafio pois acabou o nosso tempo e a sala já estava reservada. O pessoal quase conseguiu finalizar o primeiro cenário, e foi uma experiência de bastante aprendizado a todos.
Basicamente os cenários eram:
Cadastrar usuário com sucesso
Cadastrar usuário com falha de duplicidade
Cadastrar usuário com falha de itens obrigatórios
As premissas eram: escrever o código de forma que ele ficasse reutilizável e sempre pensar que o teste não era feito para ser executado uma vez só mais sim infinitas vezes.
Os códigos estão no meu github: https://github.com/cintiaarmesto/dojo-RBS-testes .
Bem a primeira experiência legal e que é o motivo desse post, trata-se de um primeiro dojo de testes funcionais usando Selenium que fizemos aqui na RBS.
No dojo reunimos testadores e desenvolvedores para que podessemos fazer uma troca legal.
O desafio era automatizar três cenários bem simples em uma ferramenta que é de uso de todo o time.
Infelizmente não foi possível acabar o desafio pois acabou o nosso tempo e a sala já estava reservada. O pessoal quase conseguiu finalizar o primeiro cenário, e foi uma experiência de bastante aprendizado a todos.
Basicamente os cenários eram:
Cadastrar usuário com sucesso
Cadastrar usuário com falha de duplicidade
Cadastrar usuário com falha de itens obrigatórios
As premissas eram: escrever o código de forma que ele ficasse reutilizável e sempre pensar que o teste não era feito para ser executado uma vez só mais sim infinitas vezes.
Os códigos estão no meu github: https://github.com/cintiaarmesto/dojo-RBS-testes .
Assinar:
Postagens (Atom)
