O que o método Assert () faz? Ainda é útil?


156

Estou depurando com pontos de interrupção e percebo a chamada de afirmação? Eu pensei que era apenas para testes de unidade. O que faz mais do que o ponto de interrupção? Como posso interromper, por que devo usar o Assert?


9
A propósito, se você estiver interessado em afirmar, definitivamente deve se aprofundar em contratos de código .
— MasterMastic 19/02

Respostas:


200

Em uma compilação de depuração, Assertobtém uma condição booleana como parâmetro e mostra a caixa de diálogo de erro se a condição for falsa. O programa continua sem interrupção se a condição for verdadeira.

Se você compilar no Release, todos Debug.Assertserão automaticamente excluídos.


12
como posso obter o mesmo comportamento do Debug.Assert no modo Release?
— Hamish Grubijan

15
Trace.Assert para o modo de liberação aparentemente refs: msdn.microsoft.com/en-us/library/... msdn.microsoft.com/en-us/library/e63efys0.aspx
— Tim Abell

8
@HamishGrubijan E por que você quer Debug.Assertno modo de lançamento?
— Camilo Martin

25
OMI, omitir declarações do código de liberação é como realizar exercícios de bote salva-vidas enquanto ancorados e, em seguida, deixar os botes salva-vidas para trás quando você navega. :)
— Chrisd

113
Afirmações não são um barco salva-vidas, são um sistema de detecção de iceberg. Como o usuário não está dirigindo o navio, uma declaração no código de liberação apenas diz que está condenado; não os deixa evitar o iceberg.
— Stefan

97

Do código completo

8 Programação defensiva

8.2 Declarações

Uma asserção é um código usado durante o desenvolvimento - geralmente uma rotina ou macro - que permite que um programa verifique a si próprio enquanto é executado. Quando uma afirmação é verdadeira, isso significa que tudo está funcionando como esperado. Quando é falso, significa que ele detectou um erro inesperado no código. Por exemplo, se o sistema assumir que um arquivo de informações do cliente nunca terá mais de 50.000 registros, o programa poderá conter uma afirmação de que o número de registros é menor ou igual a 50.000. Desde que o número de registros seja menor ou igual a 50.000, a asserção será silenciosa. Se encontrar mais de 50.000 registros, no entanto, "afirmará" que há um erro no programa.

As asserções são especialmente úteis em programas grandes e complicados e em programas de alta confiabilidade. Eles permitem que os programadores eliminem mais rapidamente suposições de interface incompatíveis, erros que surgem quando o código é modificado e assim por diante.

Uma asserção geralmente leva dois argumentos: uma expressão booleana que descreve a suposição que deveria ser verdadeira e uma mensagem a ser exibida, se não for.

(…)

Normalmente, você não deseja que os usuários vejam mensagens de asserção no código de produção; afirmações são principalmente para uso durante o desenvolvimento e manutenção. As asserções são normalmente compiladas no código no momento do desenvolvimento e compiladas do código para produção. Durante o desenvolvimento, as afirmações eliminam suposições contraditórias, condições inesperadas, valores ruins transmitidos às rotinas e assim por diante. Durante a produção, eles são compilados a partir do código para que as asserções não prejudiquem o desempenho do sistema.


2
O livro, Writing Solid Code, também tem uma ótima discussão sobre o uso de assert. Eles são uma ótima ferramenta de depuração!
— Zooropa

39

Você deve usá-lo para momentos em que não deseja interromper cada pequena linha de código para verificar variáveis, mas deseja obter algum tipo de feedback se determinadas situações estiverem presentes, por exemplo:

Debug.Assert(someObject != null, "someObject is null! this could totally be a bug!");

Se eu adicionar uma linha de código semelhante à sua acima, a execução do meu programa apresentará o seguinte erro: "erro CS0103: O nome 'Debug' não existe no contexto atual". Preciso de algum tipo de declaração de uso para fazer funcionar?
— Josh Desmond

4
@JoshDesmondSystem.Diagnostics
— Sinjai

16

A declaração também oferece outra oportunidade para você rir das habilidades de design da interface do usuário da Microsoft. Quero dizer: uma caixa de diálogo com três botões Abortar, Repetir, Ignorar e uma explicação de como interpretá-los na barra de título!


3
Abortar / Repetir / Ignorar é clássico! Foram afirmações que costumavam fazer com que o Windows 3.1 exibisse isso o tempo todo?
— Devlord #

Basicamente, é porque ele usa uma MessageBox, que como você diz remonta ao Windows 3.1, e possui apenas rótulos de botão predefinidos. Então você pode entender por que o hack surgiu, mas não por que ele ainda existe em 2008!
— 194 Joe Joe

4
@ Joe Isso é algo que só deve ser visto pelos desenvolvedores e não pelos usuários finais, portanto, atualizá-lo é provavelmente um item de prioridade extremamente baixa. Se incomoda, você pode modificar as coleções Debug.Listeners ou Trace.Listeners para substituir o manipulador padrão por um que faça o que você desejar.
— Dan Is Fiddling Por Firelight

5
E agora é 2019 agora e a mesma caixa de diálogo / botões ainda estão aqui!
— Bouke

10

A declaração permite que você afirme que uma condição (postagem ou pré) se aplica ao seu código. É uma maneira de documentar suas intenções e fazer com que o depurador o informe com uma caixa de diálogo se sua intenção não for atendida.

Ao contrário de um ponto de interrupção, o Assert acompanha o seu código e pode ser usado para adicionar detalhes adicionais sobre sua intenção.


10

A declaração pode ajudá-lo a fornecer um comportamento de mensagens separado entre teste e liberação. Por exemplo,

Debug.Assert(x > 2)

só acionará uma interrupção se você estiver executando uma compilação "debug", não uma compilação de lançamento. Há um exemplo completo desse comportamento aqui


10

Primeiro de tudo, o Assert()método está disponível para Tracee Debugclasses.
Debug.Assert()está executando apenas no modo de depuração.
Trace.Assert()está sendo executado no modo de depuração e liberação.

Aqui está um exemplo:

        int i = 1 + 3;
        // Debug.Assert method in Debug mode fails, since i == 4
        Debug.Assert(i == 3);
        Debug.WriteLine(i == 3, "i is equal to 3");

        // Trace.Assert method in Release mode is not failing.
        Trace.Assert(i == 4);
        Trace.WriteLine(i == 4, "i is equla to 4");

        Console.WriteLine("Press a key to continue...");
        Console.ReadLine();

Execute este código no modo Debug e, em seguida, no modo Release.

insira a descrição da imagem aqui

Você notará que durante o modo Debug sua Debug.Assertinstrução de código falha, você recebe uma caixa de mensagem mostrando o rastreamento de pilha atual do aplicativo. Isso não está acontecendo no modo Release, pois a Trace.Assert()condição é verdadeira (i == 4).

WriteLine() O método simplesmente oferece a opção de registrar as informações na saída do Visual Studio. insira a descrição da imagem aqui


5

As asserções aparecem fortemente no Design by Contract (DbC) que, pelo que entendi, foi introduzido / endossado por Meyer, Bertand. 1997. Contrução de software orientada a objetos.

Uma característica importante é que eles não devem produzir efeitos colaterais; por exemplo, você pode lidar com uma exceção ou executar um curso de ação diferente com uma instrução if (programação defensiva).

As asserções são usadas para verificar as condições pré / pós do contrato, o relacionamento cliente / fornecedor - o cliente deve garantir que as pré-condições do fornecedor sejam atendidas, por exemplo. envia £ 5 e o fornecedor deve garantir que as pós-condições sejam atendidas, por exemplo. entrega 12 rosas. (Apenas uma explicação simples do cliente / fornecedor - pode aceitar menos e entregar mais, mas sobre asserções). O C # também apresenta Trace.Assert (), que pode ser usado para código de versão.

Para responder à pergunta sim, eles ainda são úteis, mas podem adicionar complexidade + legibilidade ao código e tempo + dificuldade para manter. Ainda devemos usá-los? Sim, todos nós vamos usá-los? Provavelmente não, ou não, na medida em que Meyer descreve.

(Mesmo o curso de OU da Java em que aprendi essa técnica mostrava apenas exemplos simples e o restante do código não aplicava as regras de asserção DbC na maioria dos códigos, mas era assumido como sendo usado para garantir a correção do programa!)


3

A maneira como penso nisso é Debug.Assert é uma maneira de estabelecer um contrato sobre como um método deve ser chamado, concentrando-se em detalhes sobre os valores de um parâmetro (em vez de apenas o tipo). Por exemplo, se você não deve enviar um nulo no segundo parâmetro, adicione o Assert em torno desse parâmetro para dizer ao consumidor para não fazer isso.

Impede que alguém use seu código de maneira irracional. Mas também permite que esse caminho complicado chegue à produção e não transmita a mensagem desagradável a um cliente (supondo que você construa uma versão do Release).


6
É importante ressaltar, porém, que parâmetros inválidos em métodos públicos devem gerar exceções de argumento. Somente métodos privados devem validar entrada com asserções. Valores que vêm de fora são sempre suspeitos!
— Jeffrey L Whitledge
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.