English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Alcuni miglioramenti sugli assert di Python

Perché l'assert in Python non è soddisfacente?

L'uso degli assert in Python è molto semplice, puoi seguire l'assert con qualsiasi condizione di giudizio, se l'assert fallisce verrà lanciata un'eccezione.

>>> assert 1 + 1 == 2
>>> assert isinstance('Hello', str)
>>> assert isinstance('Hello', int)
Traceback (most recent call last):
 File "<input>", riga 1, in <modulo>
AssertionError

In realtà assert sembra buono, ma non è così piacevole da usare. Ad esempio, qualcuno ti dice che il programma è sbagliato, ma non ti dice dove. Spesso un assert del genere è meglio non scriverlo, scriverlo mi fa venire voglia di urlare. Lanciare un'eccezione direttamente è più veloce.

Soluzione migliorata #1

Un'idea leggermente migliorata è quella di aggiungere anche le informazioni necessarie dopo la statement assert, ad esempio così.

>>> s = "nothin is impossible."
>>> key = "nothing"
>>> assert key in s, "Chiave: '{}' non trovata nel Target: '{}'".format(key, s)
Traceback (most recent call last):
 File "<input>", riga 1, in <modulo>
AssertionError: Chiave: 'nothing' non trovata nel Target: 'nothin is impossible.'

Sembra andare bene, ma in realtà è scritto male. Supponiamo che tu sia un tester e tu debba fare migliaia di casi di test con affermazioni e verifiche. Credo che di fronte a questo metodo, nel tuo cuore ci siano milioni di cavalli galoppati.

Soluzione migliorata #2

Indipendentemente se sei un tester o uno sviluppatore, probabilmente hai sentito parlare di molti framework di test. Hai già capito cosa sto per dire? Sì, non usare il meccanismo di assertione del framework di test, non sei tu?

py.test

py.test è un framework di test leggero, quindi non ha scritto un proprio sistema di assertioni, ma ha migliorato le assertioni di Python di serie. Se un'asserzione fallisce, il framework stesso fornirà il motivo del fallimento dell'asserzione il più possibile. Questo significa che, per implementare i test con py.test, non devi modificare una singola riga di codice.

import pytest
def test_case():
  atteso = "Ciao"
  effettivo = "ciao"
  assert atteso == effettivo
if __name__ == '__main__':
  pytest.main()
"""
================================== FALLIMENTI ===================================
__________________________________ test_case __________________________________
  def test_case():
    atteso = "Ciao"
    effettivo = "ciao"
>    assert atteso == effettivo
E    assert 'Ciao' == 'ciao'
E     - Ciao
E     ? ^
E     + hello
E     ? ^
assertion_in_python.py:7: AssertionError
========================== 1 failed in 0.05 seconds ===========================
"""

unittest

Python's built-in unittest unit testing framework already has its own assertion methods self.assertXXX(), and it is not recommended to use assert XXX statements.

import unittest
class TestStringMethods(unittest.TestCase):
  def test_upper(self):
    self.assertEqual('foo'.upper(), 'FoO')
if __name__ == '__main__':
  unittest.main()
"""
Failure
Expected :'FOO'
Actual  :'FoO'
Traceback (most recent call last):
 File "assertion_in_python.py", line 6, in test_upper
  self.assertEqual('foo'.upper(), 'FoO')
AssertionError: 'FOO' != 'FoO'
"""

ptest

I really like ptest, thank you Karl master for writing such a test framework. The assertions in ptest are very readable, and you can easily complete various assertion statements with the smart hints of the IDE.

from ptest.decorator import *
from ptest.assertion import *
@TestClass()
class TestCases:
  @Test()
  def test1(self):
    actual = 'foo'
    expected = 'bar'
    assert_that(expected).is_equal_to(actual)
"""
Start to run following 1 tests:
------------------------------
...
[demo.assertion_in_python.TestCases.test1@Test] Failed with following message:
...
AssertionError: Inaspettatamente la stringa <bar> non è uguale alla stringa <foo>.
"""

Soluzione migliorata #3

Non solo io e te siamo insoddisfatti delle assertive in Python, ma tutti cercano di inventare i propri pacchetti di assertive. In questo articolo, consiglio vivamente il pacchetto assertpy, che è straordinariamente potente e molto apprezzato.

pip install assertpy

Ecco un esempio:

from assertpy import assert_that
def test_something():
  assert_that(1 + 2).is_equal_to(3)
  assert_that('foobar')\
    .is_length(6)\
    .starts_with('foo')\
    .ends_with('bar')
  assert_that(['a', 'b', 'c'])\
    .contains('a')\
    .does_not_contain('x')

Dal suo documento di homepage, puoi vedere che supporta quasi tutti i casi di test che puoi immaginare, inclusi ma non limitati alle seguenti liste.

      Stringhe

      Numeri

      Liste

      Tuple

      Dizionari

      Set

      Booleani

      Date

      File

      Oggetti

E il suo messaggio di assertiva è chiaro e conciso, senza eccessi.

Atteso che <foo> abbia lunghezza <4>, ma aveva <3>.
Atteso che <foo> sia una stringa vuota, ma non lo era.
Atteso <False>, ma non era così.
Atteso che <foo> contenga solo numeri, ma non è così.
Atteso che <123> contenga solo caratteri alfanumerici, ma non è così.
Atteso che <foo> contenga solo caratteri maiuscoli, ma non è così.
Atteso che <FOO> contenga solo caratteri minuscoli, ma non è così.
Atteso che <foo> sia uguale a <bar>, ma non è così.
Atteso che <foo> non sia uguale a <foo>, ma è così.
Atteso che <foo> sia uguale a <BAR> senza distinzione tra maiuscole e minuscole, ma non è così.

Prima di trovare assertpy, volevo scrivere un pacchetto simile, il più generale possibile. Ora, perché dovrei ricreare la ruota? Non è necessario!

Sommario

Le affermazioni svolgono un ruolo molto importante nei sistemi software, una scrittura buona può rendere il tuo sistema più stabile. In Python, la frase di affermazione predefinita ha anche un altro ruolo, se scrivi un'affermazione di tipo, l'IDE considera questo oggetto come questo tipo, quindi la suggerimento intelligente è come se avesse un aiuto divino.

Dovrebbe sostituire la frase di affermazione integrata con una funzione di affermazione di terze parti con migliore leggibilità e funzionalità più potenti, tutto dipende dalla situazione reale. Ad esempio, se hai davvero bisogno di verificare qualcosa e ti importa molto del risultato della verifica, non puoi usare assert semplici; se ti preoccupi solo di un punto che potrebbe avere problemi o far riconoscere un oggetto dall'IDE, l'assert integrato è semplice e conveniente.

Quindi, l'esperienza del progetto è molto importante. Questo è tutto il contenuto dell'articolo, spero che il contenuto di questo articolo possa aiutare la tua apprendimento o lavoro, se hai domande puoi lasciare un messaggio per l'interazione.

Dichiarazione: il contenuto di questo articolo è stato raccolto da Internet, il copyright è di proprietà del rispettivo proprietario, il contenuto è stato contribuito e caricato autonomamente dagli utenti di Internet, questo sito non detiene il diritto di proprietà, non è stato editato manualmente e non assume responsabilità legali correlate. Se trovi contenuti sospetti di violazione del copyright, ti preghiamo di inviare una e-mail a notice#oldtoolbag.com (al momento dell'invio dell'e-mail, sostituisci # con @) per segnalare, fornendo prove pertinenti. Una volta verificata, questo sito eliminerà immediatamente i contenuti sospetti di violazione del copyright.

Ti potrebbe interessare