diff --git a/packages/notification/.gitlab-ci.yml b/packages/notification/.gitlab-ci.yml
index e7b6c12343a6bfa6a3d45a2ea19511979c29f5c2..9cadb871dc906edde0c952330b3a14f0b5767a58 100644
--- a/packages/notification/.gitlab-ci.yml
+++ b/packages/notification/.gitlab-ci.yml
@@ -14,6 +14,7 @@ test:
   stage: test
   script:
     - apt update
-    - apt install -y npm
+    - apt install -y npm chromium
     - npm install
     - npm run build
+    - npm test
diff --git a/packages/notification/README.md b/packages/notification/README.md
index 65ed4e0f602a40592277e50989373d8518c4a42a..c526135489caffacf0c35c87543362169a36b877 100644
--- a/packages/notification/README.md
+++ b/packages/notification/README.md
@@ -39,6 +39,9 @@ npm install
 
 # constantly build dist/bundle.js and run a local web-server on port 8002 
 npm run watch-local
+
+# run tests
+npm test
 ```
 
 Jump to <http://localhost:8002> and you should get a demo page.
diff --git a/packages/notification/karma.conf.js b/packages/notification/karma.conf.js
new file mode 100644
index 0000000000000000000000000000000000000000..901e07806c448e53fd84367917e67267a1836771
--- /dev/null
+++ b/packages/notification/karma.conf.js
@@ -0,0 +1,23 @@
+// Trick to use the auto-downloaded puppeteer chrome binary
+process.env.CHROME_BIN = require('puppeteer').executablePath();
+
+module.exports = function(config) {
+  config.set({
+    basePath: 'dist',
+    frameworks: ['mocha', 'chai'],
+    files: [
+      './bundle.js',
+      {pattern: './**/*', included: false, watched: true, served: true},
+    ],
+    autoWatch: true,
+    browsers: ['ChromeHeadlessNoSandbox'],
+    customLaunchers: {
+      ChromeHeadlessNoSandbox: {
+        base: 'ChromeHeadless',
+        flags: ['--no-sandbox']
+      }
+    },
+    singleRun: false,
+    logLevel: config.LOG_ERROR
+  });
+}
diff --git a/packages/notification/package.json b/packages/notification/package.json
index 866dfde2cfbbef4706721f84d49637e073fbf2b7..0df207fc0d72938970947d916336245ac2e21df4 100644
--- a/packages/notification/package.json
+++ b/packages/notification/package.json
@@ -3,7 +3,14 @@
   "version": "1.0.0",
   "main": "src/index.js",
   "devDependencies": {
+    "karma": "^4.2.0",
+    "karma-chai": "^0.1.0",
+    "karma-chrome-launcher": "^3.0.0",
+    "karma-mocha": "^1.3.0",
     "node-sass": "^4.12.0",
+    "puppeteer": "^1.15.0",
+    "mocha": "^6.2.0",
+    "chai": "^4.2.0",
     "rollup": "^1.11.3",
     "rollup-plugin-commonjs": "^9.3.4",
     "rollup-plugin-copy": "^2.0.1",
@@ -12,6 +19,7 @@
     "rollup-plugin-serve": "^1.0.1",
     "rollup-plugin-terser": "^4.0.4",
     "rollup-plugin-json": "^4.0.0",
+    "rollup-plugin-multi-entry": "^2.1.0",
     "rollup-plugin-replace": "^2.2.0",
     "i18next-scanner": "^2.10.2",
     "vpu-common": "file:./vendor/common"
@@ -28,9 +36,11 @@
     "build-dev": "rollup -c --environment BUILD:development",
     "build-prod": "rollup -c --environment BUILD:production",
     "build-demo": "rollup -c --environment BUILD:demo",
+    "build-test": "rollup -c --environment BUILD:test",
     "i18next": "i18next-scanner",
     "watch": "npm run watch-local",
     "watch-local": "rollup -c --watch",
-    "watch-dev": "rollup -c --watch --environment BUILD:development"
+    "watch-dev": "rollup -c --watch --environment BUILD:development",
+    "test": "npm run build-test && karma start --singleRun"
   }
 }
diff --git a/packages/notification/rollup.config.js b/packages/notification/rollup.config.js
index d03df8d342f26e69618f1ea38be22e07328dd188..d133faf418bdca41fe07d8e5c37ad93a5cff4092 100644
--- a/packages/notification/rollup.config.js
+++ b/packages/notification/rollup.config.js
@@ -6,17 +6,19 @@ import {terser} from "rollup-plugin-terser";
 import json from 'rollup-plugin-json';
 import replace from "rollup-plugin-replace";
 import serve from 'rollup-plugin-serve';
+import multiEntry from 'rollup-plugin-multi-entry';
 
 const build = (typeof process.env.BUILD !== 'undefined') ? process.env.BUILD : 'local';
 console.log("build: " + build);
 
 export default {
-    input: 'src/demo.js',
+    input: (build != 'test') ? 'src/demo.js' : 'test/**/*.js',
     output: {
         file: 'dist/bundle.js',
         format: 'esm'
     },
     plugins: [
+        multiEntry(),
         resolve(),
         commonjs(),
         json(),
@@ -28,7 +30,7 @@ export default {
             minimize: false,
             plugins: []
         }),
-        (build !== 'local') ? terser() : false,
+        (build !== 'local' && build !== 'test') ? terser() : false,
         copy({
             targets: [
                 'assets/index.html',
diff --git a/packages/notification/test/unit.js b/packages/notification/test/unit.js
new file mode 100644
index 0000000000000000000000000000000000000000..e5bc6f75c8303b8a48130f21eda98911854d2247
--- /dev/null
+++ b/packages/notification/test/unit.js
@@ -0,0 +1,19 @@
+import '../src/vpu-notification';
+
+describe('vpu-notification basics', () => {
+  let node;
+
+  beforeEach(async () => {
+    node = document.createElement('vpu-notification');
+    document.body.appendChild(node);
+    await node.updateComplete;
+  });
+
+  afterEach(() => {
+    node.remove();
+  });
+
+  it('should render', () => {
+      expect(node).to.have.property('shadowRoot');
+  });
+});