Postagens

Mostrando postagens com o rótulo C#

Testes automatizados em sistemas autenticados com certificados digitais, usando Selenium e PhantomJS

Imagem
A automatização de testes é uma disciplina muito importante hoje em dia. Entre várias técnicas e ferramentas diferentes, uma das que podemos utilizar para termos um conjunto de testes funcionais que possam ser facilmente repetidos é o Selenium. O Selenium é uma ferramenta que permite que a execução de passos que uma pessoa faria em um browser web (Chrome, Edge, etc.) possa ser programada. Com isso, toda vez que for necessária a validação de uma nova versão de sistema ou correção, este grupo de testes pode ser rodado de forma automática. Ainda falando sobre a execução do Selenium, ele trabalha criando uma instância do respectivo browser e enviando comandos para ele. Dessa forma é feita a simulação de preenchimento de caixas de texto, cliques em botões, etc. Quando um teste automatizado com Selenium é rodado, pode-se ver todo o teste acontecendo. Entretanto, há um problema nesta abordagem. Caso a sessão do usuário que está executando os testes seja bloqueada, o Selenium não consegue...

Usando o padrão Decorator (GoF)

Imagem
O padrão Decorator, do livro Design Patterns: Elements of Reusable Object-Oriented Software , é útil quando precisamos adicionar um comportamento em uma classe já existente. Vamos demonstrar isso através de um exemplo de uma classe de acesso ao banco de dados onde será adicionado o uso de cache. Primeiro temos  nossa classe que acessará o "banco de dados". Na verdade, a nossa base nada mais é que um array em memória. Optei por fazer assim para manter a simplicidade do exemplo e focarmos no que realmente é importante. Além disso, a busca demora propositadamente 3 segundos para simularmos todo o trabalho de se acessar um recurso externo à aplicação como um banco de dados. // RepositorioConfiguracaoImpl.cs using System.Collections.Generic; using System.Threading; namespace ExemploDecorator { public class RepositorioConfiguracaoImpl : IRepositorioConfiguracao { private readonly Dictionary<string, string> _configuracoes = new Dictionary<string, str...

Criando e testando objetos com construtores privados

Imaginem a seguinte situação. Temos uma classe qualquer. Essa classe possui uma dependência. Além disso, vamos supor que a criação desse objeto seja uma coisa complexa, ou seja, não podemos simplesmente deixar que essa classe seja instanciada por um new. // MeuObjeto.cs public class MeuObjeto { public IMinhaDependencia Dependencia { get; set; } internal MeuObjeto() { // internal para garantir que apenas // a factory possa criar este objeto } public int RetornarCalculo(int a) { return Dependencia.Calcular() + a; } } // IMinhaDependencia.cs public interface IMinhaDependencia { int Calcular(); } Temos então uma classe factory para criar uma instância desse objeto. Problema resolvido, correto? Se eu precisar de uma instância dessa classe, simplesmente chamo sua factory. // MeuObjetoFactory.cs public class MeuObjetoFactory { public MeuObjeto ...

Mau uso do TryParse...

Abaixo está uma pérola onde vemos o uso incorreto do método TryParse. Temos uma string, lida de um arquivo, que contém informação de data, e é necessário colocá-la em um objeto do tipo DateTime. Veja como foi feito abaixo. public DateTime ObterDataControle() { DateTime dt = DateTime.MinValue; if (File.Exists(_caminhoArquivo)) { StreamReader sr = new StreamReader(_caminhoArquivo); try { string dateString = sr.ReadLine(); if (DateTime.TryParse(dateString, out dt)) dt = Convert.ToDateTime(dateString); } finally { sr.Close(); } } return dt; } O método TryParse retorna um bool, que indica se foi possível converter a string para o determinado tipo. Só que quando é possível efetuar a conversão, este método já coloca o valor no parâmetro que ele recebe de output. Não é necessário fazer (como foi feito no código) uma nova conversão do valor. A linha  dt = Conve...

Pérola: como remover caracteres de uma string

Encontrei este código no qual o desenvolvedor queria remover os pontos, traços e barras de um CNPJ formatado (de "12.345.678/0001-00" para "12345678000100"): string estab = string.Empty; char[] delimitadores = new char[] { '.', '/', '-' }; string[] partes = lblCNPJEstabelecimento.Text.Split(delimitadores, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < partes.Length; i++) estab = estab + partes[i]; }  Bizarro... Para remover uma única ocorrência, o método Replace é indicado: http://msdn.microsoft.com/en-us/library/fk49wtc1.aspx Outra alternativa é utilizar regular expressions: http://msdn.microsoft.com/en-us/library/system.text.regularexpressions.regex.replace%28v=VS.100%29.aspx O link abaixo possui um extension method para remover vários caracteres: http://www.csharptricks.com/blog/2006/10/remove-characters-from-string-cnet.html Mantenham o código simples e limpo... []'s

Nota rápida: Concatenando valores com caractere de separação em C#

Abaixo está um exemplo rápido de como concatenar um array de strings em uma única string, separando esses valores por um caractere. [TestMethod] public void TestarConcatenacao01() { var arr = new[] { "s1", "s2" }; var s = string.Join(";", arr); Assert.AreEqual("s1;s2", s); } [TestMethod] public void TestarConcatenacao02() { var arr = new string[] { }; var s = string.Join(";", arr); Assert.AreEqual(string.Empty, s); } [TestMethod] public void TestarConcatenacao03() { var arr = new[] { "s1" }; var s = string.Join(";", arr); Assert.AreEqual("s1", s); }  string.Join substituí com uma linha um código que acabei de ver, onde eram feitos um foreach e vários condicionais para conseguir o mesmo objetivo (umas 5 linhas, no mínimo). []'s

Operador yield no C#

Imagem
Hoje encontrei um operador no C# que desconhecia, o yield . Ele serve para manter estado quando se percorre uma coleção de objetos, e está intimente ligado à implementação do pattern Iterator dentro do C#. Na prática, ele pode ser aplicado quando temos métodos que retornam um IEnumerable . No exemplo abaixo, eu tenho um método que percorre as datas de finais de semana (Sábado e Domingo) dado um ano. Veja que este método é chamado dentro de um foreach , e cada iteração ele exibe uma data na tela. Não estou preocupado, dentro do foreach , em saber qual foi a última data que foi exibida, isso é controlado internamente durante a iteração, que vai mantendo o loop "ativo" através do operador yield . Feliz Natal e até a próxima! using System; using System.Collections.Generic; namespace TesteYield { class Program { static void Main(string[] args) { Console.WriteLine("Finais de semana de 2009:"); foreach (DateTime data in...