diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index c39e576d36979731e75f666d4ef1096eeb8f0879..50dc633695cc2dc32b2c6ca57de5d4a54c2e4165 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -5,6 +5,10 @@ before_script:
   - pip install -e .
   - pip install -r test-requirements.txt
 
+pytest:
+  script:
+    - py.test
+
 pep8:
   script:
     - pep8 wooify
diff --git a/test-requirements.txt b/test-requirements.txt
index 8098e7b9de75342569d2232691a3cd9e11ab735a..2dcafeccbe75f35aa3c01f19a8615aeb624d1e75 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -1 +1,3 @@
 pep8==1.7.0
+pytest==3.0.6
+pytest-cov==2.4.0
diff --git a/tests/static/sample_ecwid.csv b/tests/static/sample_ecwid.csv
new file mode 100644
index 0000000000000000000000000000000000000000..035f805d9edf9ed68385fd2476e0361f768cbeb6
--- /dev/null
+++ b/tests/static/sample_ecwid.csv
@@ -0,0 +1,5 @@
+name;sku;description;category1;category2;category3;image;weight;price;recommended_price;quantity;enabled;shipping_freight;fixed_shipping_rate_only;upc;brand;seo_title;seo_description;product_url;product_id
+Test 1;"testFoo";"<p><span style=""shitty-css: yes;"">The testiest of tests!</span></p>";Test Parent / Test Child 1;;;;42.00;13.37;;;yes;0.00;no;;;;;http://example.com/product1;12345654321
+Test 2;"testBar";"<p><span style=""shitty-css: yes;"">The testiest of tests!</span></p>";Test Parent / Test Child 2;;;;42.00;13.37;;;yes;0.00;no;;;;;http://example.com/product2;12345654321
+Test 3;"testQux";"<p><span style=""shitty-css: yes;"">The testiest of tests!</span></p>";Testy Test;;;;42.00;13.37;;;yes;0.00;no;;;;;http://example.com/product3;12345654321
+Test 4;"testBaz";"<p><span style=""shitty-css: yes;"">The testiest of tests!</span></p>";Test Parent / Test Child 2;;;;42.00;13.37;;;yes;0.00;no;;;;;http://example.com/product4;12345654321
diff --git a/tests/test_adapter_adapter.py b/tests/test_adapter_adapter.py
new file mode 100644
index 0000000000000000000000000000000000000000..864c7d992c1de433de67f5698802c6c1526b0546
--- /dev/null
+++ b/tests/test_adapter_adapter.py
@@ -0,0 +1,17 @@
+import os
+import pytest
+
+from wooify.adapters.adapter import Adapter
+
+def test_init():
+    with pytest.raises(NotImplementedError):
+        adapter = Adapter('foo')
+
+def test_clean_products(monkeypatch):
+    def mockparse(self, test_file):
+        self.products = [{
+            'Description': '<b>foo',
+        }]
+    monkeypatch.setattr(Adapter, 'parse', mockparse)
+    adapter = Adapter('foo')
+    clean = adapter.clean_products
diff --git a/tests/test_wooifier.py b/tests/test_wooifier.py
new file mode 100644
index 0000000000000000000000000000000000000000..533d3de15bfd358c6231e4e4d7b3e08415d3af29
--- /dev/null
+++ b/tests/test_wooifier.py
@@ -0,0 +1,33 @@
+import csv
+import os
+import pytest
+
+from wooify.wooifier import Wooifier
+from wooify.adapters.adapter import Adapter
+from wooify.constants import (ALLOWED_HTML_TAGS, HTML_FIELDS,
+                              WOO_IMP_EXP_PRODUCT_FIELDS)
+
+def test_init():
+    wooifier = Wooifier(Adapter)
+    assert wooifier.adapter_cls == Adapter
+
+def test_wooify(monkeypatch, tmpdir):
+    def mockparse(self, test_file):
+        products = [{
+            'sku': 'test1',
+            'name': 'Test 1',
+        }]
+        for p in products:
+            product = dict(WOO_IMP_EXP_PRODUCT_FIELDS)
+            product.update({'SKU': p['sku'], 'Product Name': p['name']})
+            self.products.append(product)
+    monkeypatch.setattr(Adapter, 'parse', mockparse)
+    wooifier = Wooifier(Adapter)
+    in_file = tmpdir.join("input.csv")
+    products_file = tmpdir.join("products.csv")
+    categories_file = tmpdir.join("categories.csv")
+    wooifier.wooify(in_file, products_file.strpath, categories_file.strpath)
+    csv_reader = csv.DictReader(products_file.open())
+    for row in csv_reader:
+        assert row['SKU'] == 'test1'
+        assert row['Product Name'] == 'Test 1'