Как вы проверяете, что функция Python генерирует исключение?
Как написать тест, который выходит из строя, только если функция не генерирует ожидаемое исключение?
Short Answer:
Использовать метод
self.assertRaises
в качестве менеджера контекста:def test_1_cannot_add_int_and_str(self): with self.assertRaises(TypeError): 1 + '1'
Демонстрация
довольно легко продемонстрировать в оболочке Python.
Библиотека
unittest
В Python 2.7 или 3:
import unittest
В Python 2.6 вы можете установить backport из 2.7's
unittest
, называемой unittest2 , и просто псевдоним, который какunittest
:import unittest2 as unittest
Примеры тестов
Теперь вставьте в свою оболочку Python следующую тест безопасности типа Python:
class MyTestCase(unittest.TestCase): def test_1_cannot_add_int_and_str(self): with self.assertRaises(TypeError): 1 + '1' def test_2_cannot_add_int_and_str(self): import operator self.assertRaises(TypeError, operator.add, 1, '1')
В тестовом режиме в качестве менеджера контекста используется
assertRaises
, который гарантирует, что ошибка будет правильно захвачена и очищена, при записи.Мы могли бы также написать без менеджера контекста, см. тест два. Первым аргументом будет тип ошибки, которую вы ожидаете поднять, второй аргумент, тестируемая функция, а остальные аргументы args и ключевого слова будут переданы этой функции.
Я думаю, что это гораздо проще, легко читаемо и поддерживается только для использования диспетчера контекстов.
Запуск тестов
Для запуска тестов:
unittest.main(exit=False)
В Python 2.6 вам, вероятно, понадобится следующее :
unittest.TextTestRunner().run(unittest.TestLoader().loadTestsFromTestCase(MyTestCase))
И ваш терминал должен вывести следующее:
.. ---------------------------------------------------------------------- Ran 2 tests in 0.007s OK
И мы видим, что, как мы ожидаем, попытка добавить
1
и'1'
приведет кTypeError
.Для получения более подробного вывода попробуйте следующее:
unittest.TextTestRunner(verbosity=2).run(unittest.TestLoader().loadTestsFromTestCase(MyTestCase))
Вам не нужно JavaScript
, чтобы выполнить это. Бит translateY
используется для предотвращения вращения значка в исходном положении. Значение 0.5em
означает половину высоты коробки, содержащей шеврон .
.fas.fa-chevron-down {
transition: .15s transform ease-in-out;
}
details[open] .fas.fa-chevron-down {
transform: rotate(180deg) translateY(-0.5em);
}
Демо
.card {
width: 18em;
justify-self: center;
margin: 0;
padding: 2em 1em 0;
}
.card img {
margin: 0 0 5px 0;
width: 18em;
height: auto;
}
summary {
width: 18em;
font-weight: bold;
font-family: monospace;
font-size: 1.2rem;
text-transform: uppercase;
text-align: center;
margin: 0;
padding: 0;
color: #202020;
background: #808080;
cursor: pointer;
border-bottom-left-radius: 7px;
border-bottom-right-radius: 7px;
}
summary::-webkit-details-marker {
display: none;
}
.card i {
margin: 0;
padding: 0;
font-variant-position: sub;
color: #101010;
}
.card i:active {
transform: rotate(180deg);
color: #fef;
}
summary:focus {
outline-style: none;
background: #404040;
color: #fef;
}
details {
width: 17.55em;
color: #fef;
background: #212529;
border-bottom: 1px solid rgba(250, 224, 66, .45);
border-bottom-left-radius: 7px;
border-bottom-right-radius: 7px;
padding: 0;
margin: -.25em 0 2em;
border-right: solid 1px #b5b5b5;
border-bottom: solid 1px #b5b5b5;
}
.contentul li {
padding: 1em;
}
.fas.fa-chevron-down {
transition: .15s transform ease-in-out;
}
details[open] .fas.fa-chevron-down {
transform: rotate(180deg) translateY(-0.5em);
}
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
<div class="card" id="card">
<details>
<summary><img id="img1" src="https://images.unsplash.com/photo-1503708928676-1cb796a0891e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1334&q=80" alt="ex1">Excavators<br><i class="fas fa-chevron-down"></i></summary>
<ul class="contentul">
<li>180° Wheeled</li>
<li>360° Wheeled</li>
<li>360° Tracked</li>
</ul>
</details>
</div>