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?

Pokus
fonte
9
A propósito, se você estiver interessado em afirmar, definitivamente deve se aprofundar em contratos de código .
MasterMastic 19/02
Possível duplicado de stackoverflow.com/questions/129120/...
Michael Freidgeim

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.

Patrick Desjardins
fonte
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.

juan
fonte
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!");
thelsdj
fonte
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!

Joe
fonte
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.

Jeff Yates
fonte
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

Ryan
fonte
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

Serge Voloshenko
fonte
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!)

Cavaleiro
fonte
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).

Flory
fonte
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