单元测试Django app内的弹性搜索

时间:2016-03-21 10:32:10

标签: python django unit-testing elasticsearch

我有一个使用弹性搜索的django应用程序。我想要100%的代码测试覆盖率,所以我需要测试对elasticsearch的调用(在本地“安装”)。

所以我的问题是:模拟整个弹性搜索是否更好,还是应该运行elasticserver并检查结果?

IMO最好是模拟elasticsearch并检查python代码(测试是否所有内容都使用正确的参数调用)。

2 个答案:

答案 0 :(得分:2)

您可以编写一些实际调用elasticsearch的基本集成测试,然后使用单元测试覆盖视图,模型等中的其余相关方法。通过这种方式,您可以测试所有内容,而无需模拟弹性搜索,并发现您可能不会出现的错误/行为。

我们正在使用django haystack(https://github.com/django-haystack/django-haystack),它为搜索后端提供统一的api,包括elasticsearch以及以下管理命令:

  • build_solr_schema
  • clear_index
  • haystack_info
  • rebuild_index
  • update_index

您可以将上述内容包含在基本集成测试类中以管理搜索索引。 E.g:

from django.core.management import call_command
from django.test import TestCase
from model_mommy import mommy


class IntegrationTestCase(TestCase):
    def rebuild_index(self):
        call_command('rebuild_index', verbosity=0, interactive=False)

class IntegrationTestUsers(IntegrationTestCase):
    def test_search_users_in_elasticsearch(self):
        user = mommy.make(User, first_name='John', last_name='Smith')
        user = mommy.make(User, first_name='Andy', last_name='Smith')
        user = mommy.make(User, first_name='Jane', last_name='Smith')
        self.rebuild_index()

        # Search api and verify results e.g. /api/users/?last_name=smith

答案 1 :(得分:0)

我个人认为,调用真正的Elasticsearch的测试将比嘲笑它的测试产生更多的价值和信心。并且在Django中设置测试基础架构以隔离这些测试是非常可行的:

from example.elasticsearch import search_media


def index_test_fixtures(es, index_name, data):
    created = es.index(index=index_name, body=data)
    assert created["result"] == "created"
    es.indices.refresh(index_name)


class TestElasticsearch:
    def test_elasticsearch(self, elasticsearch):
        index_test_fixtures(
            elasticsearch,
            "movie",
            {
                "slug": "episode-5",
                "title": "Star Wars: Episode V - The Empire Strikes Back",
                "description": "After the Rebels are brutally overpowered by the Empire on the ice planet Hoth, Luke Skywalker begins Jedi training with Yoda, while his friends are pursued by Darth Vader and a bounty hunter named Boba Fett all over the galaxy.",
            },
        )

        results = search_media("Star Wars")
        assert results[0]["slug"] == "episode-5"

我在个人博客https://yanglinzhao.com/posts/test-elasticsearch-in-django中写了一些有关如何设置所有配置(docker-composepytestelasticsearch等)的内容。如果有帮助的话,还有一个可行的示例演示https://github.com/yanglinz/django-pytest-elasticsearch-example