diff --git a/test/data/bootstrap_cubes b/test/data/bootstrap_cubes
index ac89237201a8d1252f59a9f7eeeaaf8f239692d4_dGVzdC9kYXRhL2Jvb3RzdHJhcF9jdWJlcw==..21b992410538ea8da81ce788fbb410ca6166e392_dGVzdC9kYXRhL2Jvb3RzdHJhcF9jdWJlcw== 100644
--- a/test/data/bootstrap_cubes
+++ b/test/data/bootstrap_cubes
@@ -1,1 +1,1 @@
-elasticsearch
+elasticsearch,blog
diff --git a/test/test_elastic_search.py b/test/test_elastic_search.py
new file mode 100644
index 0000000000000000000000000000000000000000..21b992410538ea8da81ce788fbb410ca6166e392_dGVzdC90ZXN0X2VsYXN0aWNfc2VhcmNoLnB5
--- /dev/null
+++ b/test/test_elastic_search.py
@@ -0,0 +1,128 @@
+# flake8: noqa
+from __future__ import print_function
+
+import sys
+import unittest
+from io import StringIO
+
+from mock import patch
+
+from elasticsearch_dsl.result import Response
+
+from cubicweb.devtools import testlib
+from cubicweb.cwconfig import CubicWebConfiguration
+from cubes.elasticsearch import ccplugin
+from cubes.elasticsearch.es import indexable_types, index_settings
+
+
+class ExportElasticSearchTC(testlib.AutoPopulateTest):
+    # ignore ComputedRelations
+    ignored_relations = set(
+        ('narrower_concept', 'hidden_label', 'preferred_label', 'alternative_label', ))
+
+    def setup_database(self):
+        super(ExportElasticSearchTC, self).setup_database()
+        self.orig_config_for = CubicWebConfiguration.config_for
+        config_for = lambda appid: self.config  # noqa
+        CubicWebConfiguration.config_for = staticmethod(config_for)
+
+    def to_test_etypes(self):
+        with self.admin_access.repo_cnx() as cnx:
+            types = indexable_types(cnx.repo)
+        return types
+
+    def tearDown(self):
+        CubicWebConfiguration.config_for = self.orig_config_for
+        super(ExportElasticSearchTC, self).tearDown()
+
+    def test_indexable_types(self):
+        with self.admin_access.repo_cnx() as cnx:
+            self.assertNotEquals(
+                len(indexable_types(cnx.repo)),
+                0)
+
+    @patch('elasticsearch.client.Elasticsearch.index', unsafe=True)
+    @patch('elasticsearch.client.indices.IndicesClient.create', unsafe=True)
+    def test_ccplugin(self, create, index):
+        self.auto_populate(10)
+        index.reset_mock()
+        cmd = [self.appid, '--dry-run', 'yes']
+        sys.stdout = out = StringIO()
+        try:
+            ccplugin.IndexInES(None).main_run(cmd)
+        finally:
+            sys.stdout = sys.__stdout__
+        self.assertEquals('', out.getvalue())
+        create.assert_not_called()
+        index.assert_not_called()
+
+        cmd = [self.appid, '--dry-run', 'yes', '--debug', 'yes']
+        sys.stdout = out = StringIO()
+        try:
+            ccplugin.IndexInES(None).main_run(cmd)
+        finally:
+            sys.stdout = sys.__stdout__
+        self.assert_('found ' in out.getvalue())
+        create.assert_not_called()
+        index.assert_not_called()
+
+        # TODO try wrong option
+        # cmd = [self.appid, '--wrong-option', 'yes']
+
+        cmd = [self.appid]
+        sys.stdout = StringIO()
+        try:
+            ccplugin.IndexInES(None).main_run(cmd)
+        finally:
+            sys.stdout = sys.__stdout__
+        with self.admin_access.repo_cnx() as cnx:
+            self.assert_(cnx.execute('Any X WHERE X is %(etype)s' %
+                                     {'etype': indexable_types(cnx.repo)[0]}))
+        create.assert_called_with(
+            ignore=400, index='cubicweb', body=index_settings())
+        index.assert_called()
+        # TODO ? check called data
+
+    @patch('elasticsearch.client.Elasticsearch.index', unsafe=True)
+    def test_es_hooks_create(self, index):
+        with self.admin_access.cnx() as cnx:
+            cnx.create_entity('BlogEntry', title=u'Article about stuff',
+                              content=u'content herer')
+            cnx.commit()
+            index.assert_called()
+
+    @patch('elasticsearch.client.Elasticsearch.index', unsafe=True)
+    def test_es_hooks_modify(self, index):
+        with self.admin_access.cnx() as cnx:
+            entity = cnx.create_entity('BlogEntry', title=u'Article about stuff',
+                                       content=u'content herer')
+            cnx.commit()
+            index.reset_mock()
+            entity.cw_set(title=u'Different title')
+            index.assert_called()
+
+
+
+def mock_execute(*args, **kwargs):
+    result = {'_source': {'description': 'test',
+                          'cwuri': 'http://example.org/123',
+                          'eid': 123,
+                          'title': 'test'},
+              '_type': 'BaseContent',
+              '_score': 1}
+    return Response({'hits': {'hits': [result],
+                              'total': 1
+                              }})
+
+
+class ElasticSearchViewsTC(testlib.CubicWebTC):
+
+    @patch('elasticsearch_dsl.search.Search.execute', new=mock_execute)
+    def test_search_view(self):
+        with self.new_access('anon').web_request() as req:
+            # self._cw.form.get('search'))
+            self.view('esearch', req=req, template=None)
+
+
+if __name__ == '__main__':
+    unittest.main()
diff --git a/tox.ini b/tox.ini
index ac89237201a8d1252f59a9f7eeeaaf8f239692d4_dG94LmluaQ==..21b992410538ea8da81ce788fbb410ca6166e392_dG94LmluaQ== 100644
--- a/tox.ini
+++ b/tox.ini
@@ -8,6 +8,7 @@
 sitepackages = true
 deps =
   pytest
+  cubicweb-blog
 commands =
   {envpython} -m pytest {posargs:test}