Pergunta

Usando C#, preciso de uma classe chamada User que possui nome de usuário, senha, sinalizador ativo, nome, sobrenome, nome completo, etc.

Deveria haver métodos para autenticar e salvar um usuário.Acabei de escrever um teste para os métodos?E preciso me preocupar em testar as propriedades, já que elas são getter e setters do .Net?

Foi útil?

Solução

Muitas ótimas respostas para isso também estão na minha pergunta:"Iniciando TDD - Desafios?Soluções?Recomendações?"

Posso também recomendar que você dê uma olhada no meu postagem no blog (que foi parcialmente inspirado pela minha pergunta), recebi bons comentários sobre isso.Nomeadamente:

Não sei por onde começar?

  • Começar de novo.Pense apenas em escrever testes quando estiver escrevendo um novo código.Isso pode ser reformulado do código antigo ou um recurso completamente novo.
  • Comece simples.Não saia fugindo e tentando colocar sua cabeça em torno de uma estrutura de teste, além de ser o tipo TDD.Debug.Assert funciona bem.Use-o como ponto de partida.Não mexe com o seu projeto ou cria dependências.
  • Comece positivo.Você está tentando melhorar seu ofício, se sentir bem com isso.Eu já vi muitos desenvolvedores por aí que ficam felizes em estagnar e não tentar coisas novas para melhorar a si mesmas.Você está fazendo a coisa certa, lembre -se disso e isso ajudará a impedi -lo de desistir.
  • Comece pronto para um desafio.É muito difícil começar a testar.Espere um desafio, mas lembre -se - os desafios podem ser superados.

Teste apenas o que você espera

Eu tive problemas reais quando comecei porque estava constantemente sentado lá tentando descobrir todos os problemas possíveis que poderiam ocorrer e depois tentar testá -lo e corrigir.Esta é uma maneira rápida de ter dor de cabeça.Os testes devem ser um processo Yagni real.Se você sabe que há um problema, escreva um teste para ele.Caso contrário, não se preocupe.

Teste apenas uma coisa

Cada caso de teste só deve testar uma coisa.Se você se encontrar colocando "e" no nome do caso de teste, está fazendo algo errado.

Espero que isso signifique que podemos passar de "getters e setters" :)

Outras dicas

Teste seu código, não a linguagem.

Um teste de unidade como:

Integer i = new Integer(7);
assert (i.instanceOf(integer));

só é útil se você estiver escrevendo um compilador e houver uma chance diferente de zero de que seu instanceof método não está funcionando.

Não teste coisas que você possa confiar na linguagem para aplicar.No seu caso, eu me concentraria nos métodos de autenticação e salvamento - e escreveria testes que garantissem que eles poderiam lidar com valores nulos em qualquer um ou em todos esses campos normalmente.

Isso me levou a testar unidades e me deixou muito feliz

Acabamos de começar a fazer testes de unidade.Há muito tempo eu sabia que seria bom começar a fazer isso, mas não tinha ideia de como começar e, mais importante, o que testar.

Então tivemos que reescrever um código importante em nosso programa de contabilidade.Esta parte foi muito complexa, pois envolveu muitos cenários diferentes.A parte de que estou falando é uma forma de pagamento de faturas de vendas e/ou compras já inseridas no sistema contábil.

Eu simplesmente não sabia como começar a codificá-lo, pois havia tantas opções de pagamento diferentes.Uma fatura poderia custar US$ 100, mas o cliente transferiu apenas US$ 99.Talvez você tenha enviado faturas de vendas a um cliente, mas também tenha comprado desse cliente.Então você o vendeu por US$ 300, mas comprou por US$ 100.Você pode esperar que seu cliente pague $ 200 para liquidar o saldo.E se você vendesse por US$ 500, mas o cliente pagasse apenas US$ 250?

Então eu tive um problema muito complexo para resolver com muitas possibilidades de que um cenário funcionaria perfeitamente, mas estaria errado em outro tipo de combinação de fatura/pagamento.

Foi aqui que os testes unitários vieram em socorro.

Comecei a escrever (dentro do código de teste) um método para criar uma lista de faturas, tanto de vendas quanto de compras.Então escrevi um segundo método para criar o pagamento real.Normalmente, um usuário inseriria essas informações por meio de uma interface de usuário.

Então criei o primeiro TestMethod, testando um pagamento muito simples de uma única fatura sem nenhum desconto no pagamento.Toda a ação no sistema aconteceria quando um pagamento bancário fosse salvo no banco de dados.Como você pode ver, criei uma fatura, criei um pagamento (uma transação bancária) e salvei a transação em disco.Nas minhas afirmações coloquei quais deveriam ser os números corretos que terminam na transação bancária e na fatura vinculada.Verifico a quantidade de pagamentos, os valores dos pagamentos, o valor do desconto e o saldo da fatura após a transação.

Após a execução do teste, eu iria ao banco de dados e verificaria se o que eu esperava estava lá.

Depois Eu escrevi o teste, comecei a codificar a forma de pagamento (parte da classe BankHeader).Na codificação eu só me preocupei com o código para fazer o primeiro teste passar.Ainda não pensei nos outros cenários mais complexos.

Executei o primeiro teste, consertei um pequeno bug até que meu teste fosse aprovado.

Aí comecei a escrever o segundo teste, dessa vez trabalhando com desconto no pagamento.Depois de escrever o teste, modifiquei a forma de pagamento para oferecer suporte a descontos.

Ao testar a correção com desconto no pagamento, também testei o pagamento simples.Ambos os testes devem passar, é claro.

Depois, fui até os cenários mais complexos.

1) Pense em um novo cenário

2) Escreva um teste para esse cenário

3) Execute aquele único teste para ver se ele passaria

4) Do contrário, eu depuraria e modificaria o código até que ele passasse.

5) Ao modificar o código continuei executando todos os testes

Foi assim que consegui criar meu método de pagamento muito complexo.Sem testes unitários eu não sabia como começar a codificar, o problema parecia esmagador.Com os testes eu poderia começar com um método simples e estendê-lo passo a passo com a garantia de que os cenários mais simples ainda funcionariam.

Tenho certeza de que o uso de testes unitários me economizou alguns dias (ou semanas) de codificação e está mais ou menos garantindo a correção do meu método.

Se mais tarde eu pensar em um novo cenário, posso simplesmente adicioná-lo aos testes para ver se está funcionando ou não.Caso contrário, posso modificar o código, mas ainda ter certeza de que os outros cenários ainda estão funcionando corretamente.Isso economizará dias e dias na fase de manutenção e correção de bugs.

Sim, mesmo o código testado ainda pode ter bugs se um usuário fizer coisas que você não pensou ou o impediu de fazer

Abaixo estão apenas alguns dos testes que criei para testar minha forma de pagamento.

public class TestPayments
{
    InvoiceDiaryHeader invoiceHeader = null;
    InvoiceDiaryDetail invoiceDetail = null;
    BankCashDiaryHeader bankHeader = null;
    BankCashDiaryDetail bankDetail = null;



    public InvoiceDiaryHeader CreateSales(string amountIncVat, bool sales, int invoiceNumber, string date)
    {
        ......
        ......
    }

    public BankCashDiaryHeader CreateMultiplePayments(IList<InvoiceDiaryHeader> invoices, int headerNumber, decimal amount, decimal discount)
    {
       ......
       ......
       ......
    }


    [TestMethod]
    public void TestSingleSalesPaymentNoDiscount()
    {
        IList<InvoiceDiaryHeader> list = new List<InvoiceDiaryHeader>();
        list.Add(CreateSales("119", true, 1, "01-09-2008"));
        bankHeader = CreateMultiplePayments(list, 1, 119.00M, 0);
        bankHeader.Save();

        Assert.AreEqual(1, bankHeader.BankCashDetails.Count);
        Assert.AreEqual(1, bankHeader.BankCashDetails[0].Payments.Count);
        Assert.AreEqual(119M, bankHeader.BankCashDetails[0].Payments[0].PaymentAmount);
        Assert.AreEqual(0M, bankHeader.BankCashDetails[0].Payments[0].PaymentDiscount);
        Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[0].InvoiceHeader.Balance);
    }

    [TestMethod]
    public void TestSingleSalesPaymentDiscount()
    {
        IList<InvoiceDiaryHeader> list = new List<InvoiceDiaryHeader>();
        list.Add(CreateSales("119", true, 2, "01-09-2008"));
        bankHeader = CreateMultiplePayments(list, 2, 118.00M, 1M);
        bankHeader.Save();

        Assert.AreEqual(1, bankHeader.BankCashDetails.Count);
        Assert.AreEqual(1, bankHeader.BankCashDetails[0].Payments.Count);
        Assert.AreEqual(118M, bankHeader.BankCashDetails[0].Payments[0].PaymentAmount);
        Assert.AreEqual(1M, bankHeader.BankCashDetails[0].Payments[0].PaymentDiscount);
        Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[0].InvoiceHeader.Balance);
    }

    [TestMethod]
    [ExpectedException(typeof(ApplicationException))]
    public void TestDuplicateInvoiceNumber()
    {
        IList<InvoiceDiaryHeader> list = new List<InvoiceDiaryHeader>();
        list.Add(CreateSales("100", true, 2, "01-09-2008"));
        list.Add(CreateSales("200", true, 2, "01-09-2008"));

        bankHeader = CreateMultiplePayments(list, 3, 300, 0);
        bankHeader.Save();
        Assert.Fail("expected an ApplicationException");
    }

    [TestMethod]
    public void TestMultipleSalesPaymentWithPaymentDiscount()
    {
        IList<InvoiceDiaryHeader> list = new List<InvoiceDiaryHeader>();
        list.Add(CreateSales("119", true, 11, "01-09-2008"));
        list.Add(CreateSales("400", true, 12, "02-09-2008"));
        list.Add(CreateSales("600", true, 13, "03-09-2008"));
        list.Add(CreateSales("25,40", true, 14, "04-09-2008"));

        bankHeader = CreateMultiplePayments(list, 5, 1144.00M, 0.40M);
        bankHeader.Save();

        Assert.AreEqual(1, bankHeader.BankCashDetails.Count);
        Assert.AreEqual(4, bankHeader.BankCashDetails[0].Payments.Count);
        Assert.AreEqual(118.60M, bankHeader.BankCashDetails[0].Payments[0].PaymentAmount);
        Assert.AreEqual(400, bankHeader.BankCashDetails[0].Payments[1].PaymentAmount);
        Assert.AreEqual(600, bankHeader.BankCashDetails[0].Payments[2].PaymentAmount);
        Assert.AreEqual(25.40M, bankHeader.BankCashDetails[0].Payments[3].PaymentAmount);

        Assert.AreEqual(0.40M, bankHeader.BankCashDetails[0].Payments[0].PaymentDiscount);
        Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[1].PaymentDiscount);
        Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[2].PaymentDiscount);
        Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[3].PaymentDiscount);

        Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[0].InvoiceHeader.Balance);
        Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[1].InvoiceHeader.Balance);
        Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[2].InvoiceHeader.Balance);
        Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[3].InvoiceHeader.Balance);
    }

    [TestMethod]
    public void TestSettlement()
    {
        IList<InvoiceDiaryHeader> list = new List<InvoiceDiaryHeader>();
        list.Add(CreateSales("300", true, 43, "01-09-2008")); //Sales
        list.Add(CreateSales("100", false, 6453, "02-09-2008")); //Purchase

        bankHeader = CreateMultiplePayments(list, 22, 200, 0);
        bankHeader.Save();

        Assert.AreEqual(1, bankHeader.BankCashDetails.Count);
        Assert.AreEqual(2, bankHeader.BankCashDetails[0].Payments.Count);
        Assert.AreEqual(300, bankHeader.BankCashDetails[0].Payments[0].PaymentAmount);
        Assert.AreEqual(-100, bankHeader.BankCashDetails[0].Payments[1].PaymentAmount);
        Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[0].InvoiceHeader.Balance);
        Assert.AreEqual(0, bankHeader.BankCashDetails[0].Payments[1].InvoiceHeader.Balance);
    }

Se eles realmente são triviais, não se preocupe em testar.Por exemplo, se forem implementados desta forma;

public class User
{
    public string Username { get; set; }
    public string Password { get; set; }
}

Se, por outro lado, você estiver fazendo algo inteligente (como criptografar e descriptografar a senha no getter/setter), faça um teste.

A regra é que você deve testar cada parte da lógica que escreve.Se você implementou alguma funcionalidade específica nos getters e setters, acho que vale a pena testá-los.Se eles atribuirem valores apenas a alguns campos privados, não se preocupe.

Esta questão parece ser uma questão de onde se traça o limite sobre quais métodos são testados e quais não.

Os setters e getters para atribuição de valor foram criados pensando na consistência e no crescimento futuro, e prevendo que em algum momento o setter/getter poderá evoluir para operações mais complexas.Faria sentido implementar testes unitários desses métodos, também por uma questão de consistência e crescimento futuro.

A confiabilidade do código, especialmente durante mudanças para adicionar funcionalidades adicionais, é o objetivo principal.Não tenho conhecimento de alguém que tenha sido demitido por incluir setters/getters na metodologia de teste, mas tenho certeza de que existem pessoas que gostariam de ter testado métodos que, pela última vez, sabiam ou lembram que eram simples set/get wrappers, mas isso não foi mais o caso.

Talvez outro membro da equipe tenha expandido os métodos set/get para incluir lógica que agora precisa ser testada, mas não criou os testes.Mas agora seu código está chamando esses métodos e você não sabe que eles mudaram e precisam de testes aprofundados, e os testes que você faz no desenvolvimento e no controle de qualidade não acionam o defeito, mas os dados reais de negócios no primeiro dia de lançamento sim acioná-lo.

Os dois companheiros de equipe agora debaterão sobre quem deixou cair a bola e falhou em realizar testes de unidade quando o conjunto/é transformado para incluir uma lógica que pode falhar, mas não é coberta por um teste de unidade.O colega de equipe que originalmente escreveu o set/gets terá mais facilidade em sair dessa limpeza se os testes foram implementados desde o primeiro dia nos set/gets simples.

Minha opinião é que alguns minutos de tempo "desperdiçado" cobrindo TODOS os métodos com testes unitários, mesmo os triviais, podem poupar dias de dor de cabeça no futuro e perda de dinheiro/reputação do negócio e perda do emprego de alguém.

E o fato de você ter agrupado métodos triviais com testes de unidade pode ser visto por aquele colega de equipe júnior quando eles transformam os métodos triviais em métodos não triviais e os solicitam a atualizar o teste, e agora ninguém está com problemas porque o defeito foi contido de atingir a produção.

A maneira como codificamos e a disciplina que pode ser vista em nosso código podem ajudar outras pessoas.

Outra resposta canônica.Acredito que isso seja de Ron Jeffries:

Teste apenas o código que você deseja que funcione.

Testar código padrão é uma perda de tempo, mas como diz Slavo, se você adicionar um efeito colateral aos seus getters/setters, deverá escrever um teste para acompanhar essa funcionalidade.

Se você estiver fazendo desenvolvimento orientado a testes, você deve primeiro escrever o contrato (por exemplo, interface) e depois escrever o(s) teste(s) para exercitar essa interface que documenta os resultados/comportamento esperados. Então escreva seus próprios métodos, sem tocar no código em seus testes de unidade.Por fim, pegue uma ferramenta de cobertura de código e certifique-se de que seus testes exercitem todos os caminhos lógicos do seu código.

Códigos realmente triviais, como getters e setters, que não têm nenhum comportamento extra além de definir um campo privado, são um exagero para testar.No 3.0 C# ainda tem algum açúcar sintático onde o compilador cuida do campo privado para que você não precise programá-lo.

Normalmente escrevo muitos testes simples para verificar o comportamento que espero das minhas aulas.Mesmo que seja algo simples como somar dois números.Eu alterno muito entre escrever um teste simples e escrever algumas linhas de código.A razão para isso é que posso alterar o código sem ter medo de quebrar coisas nas quais não pensei.

Você deveria testar tudo.No momento você tem getters e setters, mas um dia você poderá alterá-los um pouco, talvez para fazer validação ou outra coisa.Os testes que você escreve hoje serão usados ​​amanhã para garantir que tudo continue funcionando normalmente.Ao escrever o teste, você deve esquecer considerações como "agora é trivial".Em um contexto ágil ou orientado a testes, você deve testar assumindo refatorações futuras.Além disso, você tentou inserir valores realmente estranhos, como strings extremamente longas ou outro conteúdo "ruim"?Bem, você deveria...nunca presuma o quanto seu código pode sofrer abusos no futuro.

Geralmente acho que escrever testes de usuário extensos é, por um lado, exaustivo.Por outro lado, embora sempre forneça informações valiosas sobre como seu aplicativo deve funcionar e ajude você a descartar suposições fáceis (e falsas) (como:o nome de usuário sempre terá menos de 1.000 caracteres).

Para módulos simples que podem acabar em um kit de ferramentas ou em um tipo de projeto de código aberto, você deve testar o máximo possível, incluindo os getters e setters triviais.O que você deve ter em mente é que gerar um teste de unidade enquanto você escreve um módulo específico é bastante simples e direto.Adicionar getters e setters é um código mínimo e pode ser feito sem muita reflexão.No entanto, uma vez que seu código é colocado em um sistema maior, esse esforço extra pode protegê-lo contra alterações no sistema subjacente, como alterações de tipo em uma classe base.Testar tudo é a melhor maneira de ter uma regressão completa.

Não custa nada escrever testes unitários para seus getters e setters.No momento, eles podem estar apenas executando get/sets de campo nos bastidores, mas no futuro você poderá ter lógica de validação ou dependências entre propriedades que precisam ser testadas.É mais fácil escrevê-lo agora, enquanto você pensa sobre isso, do que lembrar de adaptá-lo se esse momento chegar.

em geral, quando um método é definido apenas para determinados valores, teste os valores em e acabou a fronteira do que é aceitável.Em outras palavras, certifique-se de que seu método faça o que deveria fazer, mas nada mais.Isso é importante porque quando você vai falhar, você quer falhar cedo.

Em hierarquias de herança, certifique-se de testar PSL conformidade.

Testar getters e setters padrão não me parece muito útil, a menos que você planeje fazer alguma validação mais tarde.

Pelo que entendi os testes unitários no contexto do desenvolvimento ágil, Mike, sim, você precisa testar os getters e setters (supondo que sejam visíveis publicamente).Todo o conceito de teste unitário é testar a unidade de software, que neste caso é uma classe, como um caixa preta.Como os getters e setters são visíveis externamente, você precisa testá-los junto com Authenticate e Save.

Se os métodos Authenticate e Save usarem as propriedades, seus testes tocarão indiretamente nas propriedades.Contanto que as propriedades forneçam apenas acesso aos dados, testes explícitos não deverão ser necessários (a menos que você pretenda uma cobertura de 100%).

Eu testaria seus getters e setters.Dependendo de quem está escrevendo o código, algumas pessoas mudam o significado dos métodos getter/setter.Já vi inicialização de variáveis ​​e outras validações como parte de métodos getter.Para testar esse tipo de coisa, você deseja testes de unidade que cubram esse código explicitamente.

Pessoalmente, eu "testaria qualquer coisa que pudesse quebrar" e o getter simples (ou propriedades automáticas ainda melhores) não quebraria.Nunca tive uma simples declaração de retorno falhando e, portanto, nunca fiz testes para elas.Se os getters contiverem cálculos ou alguma outra forma de instrução, eu certamente adicionaria testes para eles.

Pessoalmente eu uso Quantidade mínima como uma estrutura de objeto simulada e, em seguida, verifique se meu objeto chama os objetos ao redor da maneira que deveria.

Você tem que cobrir a execução de cada método da classe com UT e verificar o valor de retorno do método.Isso inclui getters e setters, especialmente caso os membros (propriedades) sejam classes complexas, o que requer grande alocação de memória durante sua inicialização.Chame o setter com alguma string muito grande, por exemplo (ou algo com símbolos gregos) e verifique se o resultado está correto (não truncado, a codificação é boa, etc.)

No caso de números inteiros simples, isso também se aplica - o que acontece se você passar long em vez de inteiro?Essa é a razão pela qual você escreve UT :)

Eu não testaria a configuração real das propriedades.Eu ficaria mais preocupado em saber como essas propriedades são preenchidas pelo consumidor e com o que eles as preenchem.Com qualquer teste, você deve pesar os riscos com o tempo/custo do teste.

Você deve testar "cada bloco de código não trivial" usando testes de unidade, tanto quanto possível.

Se suas propriedades são triviais e é improvável que alguém introduza um bug nelas, então deve ser seguro não testá-las na unidade.

Seus métodos Authenticate() e Save() parecem bons candidatos para teste.

Idealmente, você teria feito seus testes de unidade enquanto escrevia a aula.É assim que você deve fazer ao usar o Desenvolvimento Orientado a Testes.Você adiciona os testes à medida que implementa cada ponto de função, certificando-se de cobrir os casos extremos com teste também.

Escrever os testes depois é muito mais doloroso, mas factível.

Aqui está o que eu faria na sua posição:

  1. Escreva um conjunto básico de testes que testem a função principal.
  2. Obtenha o NCover e execute-o em seus testes.A cobertura do seu teste provavelmente será em torno de 50% neste momento.
  3. Continue adicionando testes que cubram seus casos extremos até obter uma cobertura de cerca de 80% -90%

Isso deve fornecer um bom conjunto funcional de testes unitários que atuarão como um bom buffer contra regressões.

O único problema com esta abordagem é que o código tem que ser projetado para ser testável desta forma.Se você cometeu algum erro de acoplamento no início, não conseguirá obter uma cobertura alta com muita facilidade.

É por isso que é realmente importante escrever os testes antes de escrever o código.Isso força você a escrever código fracamente acoplado.

Não teste código obviamente funcional (padrão).Portanto, se seus setters e getters são apenas "propertyvalue = value" e "return propertyvalue", não faz sentido testá-los.

Mesmo get/set podem ter consequências estranhas, dependendo de como foram implementados, portanto devem ser tratados como métodos.

Cada teste destes precisará especificar conjuntos de parâmetros para as propriedades, definindo propriedades aceitáveis ​​e inaceitáveis ​​para garantir que as chamadas retornem/falhem da maneira esperada.

Você também precisa estar ciente das dicas de segurança, como exemplo de injeção de SQL, e testá-las.

Então sim, você precisa se preocupar em testar as propriedades.

Acredito que seja bobagem testar getters e setters quando eles fazem apenas uma operação simples.Pessoalmente, não escrevo testes unitários complexos para cobrir qualquer padrão de uso.Tento escrever testes suficientes para garantir que lidei com o comportamento normal de execução e com o máximo de casos de erro que consigo imaginar.Escreverei mais testes unitários em resposta aos relatórios de bugs.Eu uso o teste de unidade para garantir que o código atenda aos requisitos e para facilitar modificações futuras.Sinto-me muito mais disposto a alterar o código quando sei que, se quebrar algo, um teste falhará.

Eu escreveria um teste para qualquer coisa para a qual você esteja escrevendo código que possa ser testado fora da interface GUI.

Normalmente, qualquer lógica que eu escrevo que tenha alguma lógica de negócios é colocada dentro de outra camada ou camada de lógica de negócios.

Então é fácil escrever testes para qualquer coisa que faça alguma coisa.

Primeiramente, escreva um teste de unidade para cada método público em sua "Camada Lógica de Negócios".

Se eu tivesse uma aula assim:

   public class AccountService
    {
        public void DebitAccount(int accountNumber, double amount)
        {

        }

        public void CreditAccount(int accountNumber, double amount)
        {

        }

        public void CloseAccount(int accountNumber)
        {

        }
    }

A primeira coisa que eu faria antes de escrever qualquer código, sabendo que teria que executar essas ações, seria começar a escrever testes de unidade.

   [TestFixture]
    public class AccountServiceTests
    {
        [Test]
        public void DebitAccountTest()
        {

        }

        [Test]
        public void CreditAccountTest()
        {

        }

        [Test]
        public void CloseAccountTest()
        {

        }
    }

Escreva seus testes para validar o código que você escreveu para fazer alguma coisa.Se você estiver iterando uma coleção de coisas e mudando algo em cada uma delas, escreva um teste que faça a mesma coisa e afirme que realmente aconteceu.

Existem muitas outras abordagens que você pode adotar, como o Behavoir Driven Development (BDD), que é mais envolvente e não é um ótimo lugar para começar com suas habilidades de teste de unidade.

Então, a moral da história é: teste qualquer coisa que faça qualquer coisa que o preocupe, mantenha os testes unitários testando coisas específicas que são pequenas, muitos testes são bons.

Mantenha sua lógica de negócios fora da camada da interface do usuário para que você possa escrever testes facilmente para eles e você se sairá bem.

Eu recomendo TestDriven.Net ou ReSharper já que ambos se integram facilmente ao Visual Studio.

bem, se você acha que pode quebrar, escreva um teste para isso.Eu normalmente não testo setter/getter, mas digamos que você faça um para User.Name, que concatena nome e sobrenome, eu escreveria um teste para que se alguém alterasse a ordem do sobrenome e do nome, pelo menos ele saberia ele mudou algo que foi testado.

A resposta canônica é "teste qualquer coisa que possa quebrar". Se você tem certeza de que as propriedades não quebram, não as teste.

E quando algo está quebrado (você encontra um bug), obviamente significa que você precisa testá-lo.Escreva um teste para reproduzir o bug, observe sua falha, corrija o bug e observe o teste passar.

Eu recomendaria escrever vários testes para seus métodos Authenticate e Save.Além do caso de sucesso (onde todos os parâmetros são fornecidos, tudo está escrito corretamente, etc), é bom ter testes para vários casos de falha (parâmetros incorretos ou ausentes, conexões de banco de dados indisponíveis, se aplicável, etc).Eu recomendo Teste de unidade pragmático em C# com NUnit como referência.

Como outros já afirmaram, os testes unitários para getters e setters são um exagero, a menos que haja lógica condicional em seus getters e setters.

Embora seja possível adivinhar corretamente onde seu código precisa ser testado, geralmente acho que você precisa de métricas para respaldar essa suposição.Os testes unitários, na minha opinião, andam de mãos dadas com as métricas de cobertura de código.

Código com muitos testes, mas com uma pequena cobertura, não foi bem testado.Dito isso, código com 100% de cobertura, mas sem testar os limites e os casos de erro, também não é bom.

Você deseja um equilíbrio entre alta cobertura (mínimo de 90%) e dados de entrada variáveis.

Lembre-se de testar se há "lixo"!

Além disso, um teste de unidade não é um teste de unidade, a menos que verifique se há falha.Os testes de unidade que não possuem declarações ou são marcados com exceções conhecidas simplesmente testarão se o código não morre quando executado!

Você precisa projetar seus testes para que eles sempre relatem falhas ou dados inesperados/indesejados!

Isso torna nosso código melhor ...período!

Uma coisa que nós, desenvolvedores de software, esquecemos ao fazer desenvolvimento orientado a testes é o propósito por trás de nossas ações.Se um teste de unidade estiver sendo escrito depois que o código de produção já estiver instalado, o valor do teste diminuirá (mas não será completamente perdido).

No verdadeiro espírito dos testes unitários, esses testes são não principalmente para "testar" mais nosso código;ou para obter uma cobertura de código 90% a 100% melhor.Estes são todos benefícios adicionais de escrever os testes primeiro.A grande recompensa é que nosso código de produção acaba sendo escrito muito melhor devido ao processo natural do TDD.

Para ajudar a comunicar melhor essa ideia, o seguinte pode ser útil na leitura:

A teoria falha dos testes unitários
Desenvolvimento de software proposital

Se sentirmos que o ato de escrever mais testes unitários é o que nos ajuda a obter um produto de maior qualidade, então podemos estar sofrendo de um Culto à Carga de Desenvolvimento Orientado a Testes.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top