На самом деле это отличный вопрос!Я бы сказал, что ваш инстинкт определенно прав: если все, что вам нужно, это Doc
объект в заданном состоянии и с заданными аннотациями, всегда создавайте его вручную, где это возможно.И если вы не явно тестируете статистическую модель, не загружайте ее в свои модульные тесты.Это замедляет тестирование и вносит слишком много ненужных отклонений.Это также очень согласуется с философией модульного тестирования: вы хотите писать независимые тесты для по одной вещи за (не одна вещь плюс куча стороннего библиотечного кода плюс статистическая модель).
Некоторые общие советы и идеи:
- Если возможно, всегда создавайте
Doc
вручную.Избегайте загрузки моделей или Language
подклассов. - Если вашему приложению или тесту не требуется конкретно
doc.text
, не нужно устанавливать spaces
.Фактически, я пропускаю это примерно в 80% написанных мною тестов, потому что это действительно становится актуальным, только когда вы собираете токены обратно. - Если вам нужно создать много
Doc
объекты в вашем тестовом наборе, вы можете рассмотреть возможность использования служебной функции, аналогичной get_doc
helper , который мы используем в тестовом наборе spaCy.(Эта функция также показывает вам, как отдельные аннотации устанавливаются вручную, если вам это нужно.) - Использование (в рамках сеанса) осветителей для общих объектов, таких как
Vocab
.В зависимости от того, что вы тестируете, вы можете явно использовать English
vocab.В тестовом наборе spaCy мы делаем это, настраивая прибор en_vocab
в conftest.py
. - Вместо того, чтобы устанавливать
doc.ents
в список кортежей, вы можететакже составьте список из Span
объектов.Это выглядит немного проще, проще для чтения, и в spaCy v2.1 + вы также можете передать строку в качестве метки:
def test_entities(en_vocab):
doc = Doc(en_vocab, words=["Hello", "world"])
doc.ents = [Span(doc, 0, 1, label="ORG")]
assert doc.ents[0].text == "Hello"
- Если вам нужнопротестируйте модель (например, в наборе тестов, который гарантирует, что ваши пользовательские модели загружаются и работают должным образом) или языковой класс, такой как
English
, поместите их в фиксацию в рамках сеанса.Это означает, что они будут загружаться только один раз за сеанс, а не один раз за тест.Языковые классы загружаются с отложенной загрузкой, и их загрузка может занять некоторое время, в зависимости от содержащихся в них данных.Таким образом, вы хотите сделать это только один раз.
# Note: You probably don't have to do any of this, unless you're testing your
# own custom models or language classes.
@pytest.fixture(scope="session")
def en_core_web_sm():
return spacy.load("en_core_web_sm")
@pytest.fixture(scope="session")
def en_lang_class():
lang_cls = spacy.util.get_lang_class("en")
return lang_cls()
def test(en_lang_class):
doc = en_lang_class("Hello world")