diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 8de33ee9869141beb2d80e46118830d25041f54f..cb6839da39999ed987596c885dbb2aa6c5198acf 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -13,4 +13,5 @@ include:
   - local: '/build/ci/.code-quality-ci.yml'
   - local: '/build/ci/.documentation-ci.yml'
   - local: '/build/ci/.security-and-compliance-ci.yml'
-  - local: '/build/ci/.build-container.yml'
\ No newline at end of file
+  - local: '/build/ci/.build-container.yml'
+  - local: '/build/ci/.test.yml'
\ No newline at end of file
diff --git a/build/ci/.test.yml b/build/ci/.test.yml
new file mode 100644
index 0000000000000000000000000000000000000000..b3baa445bde403db789d7b0df5074bfbbf28fba1
--- /dev/null
+++ b/build/ci/.test.yml
@@ -0,0 +1,26 @@
+unit-test-master:
+  image: golang/golang:1.14
+  stage: test
+  rules:
+    - if: $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH
+    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
+  script:
+    - go test -coverprofile=coverage.txt -covermode count ./nucleus
+    - gocover-cobertura < coverage.txt > coverage.xml
+  artifacts:
+    reports:
+      cobertura: coverage.xml
+
+
+unit-test:
+  image: golang/golang:1.14
+  stage: test
+  allow_failure: true
+  rules:
+    - if: $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME != $CI_DEFAULT_BRANCH
+  script:
+    - go test -coverprofile=coverage.txt -covermode count ./nucleus
+    - gocover-cobertura < coverage.txt > coverage.xml
+  artifacts:
+    reports:
+      cobertura: coverage.xml
diff --git a/go.mod b/go.mod
index 2ee58ea728a76d130fa59bf80d99c4410a83c6b9..7a39f3f926c9d71ae3345171839222a20cf36e48 100644
--- a/go.mod
+++ b/go.mod
@@ -6,7 +6,6 @@ require (
 	code.fbi.h-da.de/cocsn/swagger/apis v0.0.0-20200924152423-61030cab7b88
 	code.fbi.h-da.de/cocsn/yang-models v0.0.4
 	github.com/aristanetworks/goarista v0.0.0-20201120222254-94a892eb0c6a
-	github.com/gdamore/tcell/v2 v2.0.1-0.20201017141208-acf90d56d591
 	github.com/go-openapi/runtime v0.19.22
 	github.com/go-openapi/strfmt v0.19.5
 	github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
@@ -16,9 +15,7 @@ require (
 	github.com/neo4j/neo4j-go-driver v1.8.3
 	github.com/openconfig/gnmi v0.0.0-20200617225440-d2b4e6a45802
 	github.com/openconfig/goyang v0.2.3
-	github.com/openconfig/reference v0.0.0-20190727015836-8dfd928c9696
 	github.com/openconfig/ygot v0.10.0
-	github.com/rivo/tview v0.0.0-20201018122409-d551c850a743
 	github.com/sirupsen/logrus v1.4.2
 	github.com/spf13/viper v1.7.1
 	github.com/stretchr/testify v1.6.1
diff --git a/nucleus/southbound_test.go b/nucleus/southbound_test.go
index bc36b6ac2aa53737ba7103db604a8b15c63c033f..0fa4ffa903a1f894325aaf5211341e19a2df754a 100644
--- a/nucleus/southbound_test.go
+++ b/nucleus/southbound_test.go
@@ -1,249 +1 @@
 package nucleus
-
-import (
-	gpb "github.com/openconfig/gnmi/proto/gnmi"
-	"github.com/openconfig/goyang/pkg/yang"
-	"github.com/openconfig/ygot/ytypes"
-	"reflect"
-	"testing"
-)
-
-func TestAristaOC_SbiIdentifier(t *testing.T) {
-	type fields struct {
-		transport Transport
-		schema    *ytypes.Schema
-	}
-	tests := []struct {
-		name   string
-		fields fields
-		want   string
-	}{
-		// TODO: Add test cases.
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			oc := &AristaOC{
-				transport: tt.fields.transport,
-				schema:    tt.fields.schema,
-			}
-			if got := oc.SbiIdentifier(); got != tt.want {
-				t.Errorf("SbiIdentifier() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
-
-func TestAristaOC_Schema(t *testing.T) {
-	type fields struct {
-		transport Transport
-		schema    *ytypes.Schema
-	}
-	tests := []struct {
-		name   string
-		fields fields
-		want   *ytypes.Schema
-	}{
-		// TODO: Add test cases.
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			oc := &AristaOC{
-				transport: tt.fields.transport,
-				schema:    tt.fields.schema,
-			}
-			if got := oc.Schema(); !reflect.DeepEqual(got, tt.want) {
-				t.Errorf("Schema() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
-
-func TestAristaOC_SetNode(t *testing.T) {
-	type fields struct {
-		transport Transport
-		schema    *ytypes.Schema
-	}
-	tests := []struct {
-		name   string
-		fields fields
-		want   func(schema *yang.Entry, root interface{}, path *gpb.Path, val interface{}, opts ...ytypes.SetNodeOpt) error
-	}{
-		// TODO: Add test cases.
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			oc := &AristaOC{
-				transport: tt.fields.transport,
-				schema:    tt.fields.schema,
-			}
-			if got := oc.SetNode(); !reflect.DeepEqual(got, tt.want) {
-				t.Errorf("SetNode() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
-
-func TestOpenConfig_SbiIdentifier(t *testing.T) {
-	type fields struct {
-		transport Transport
-		schema    *ytypes.Schema
-	}
-	tests := []struct {
-		name   string
-		fields fields
-		want   string
-	}{
-		// TODO: Add test cases.
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			oc := &OpenConfig{
-				transport: tt.fields.transport,
-				schema:    tt.fields.schema,
-			}
-			if got := oc.SbiIdentifier(); got != tt.want {
-				t.Errorf("SbiIdentifier() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
-
-func TestOpenConfig_Schema(t *testing.T) {
-	type fields struct {
-		transport Transport
-		schema    *ytypes.Schema
-	}
-	tests := []struct {
-		name   string
-		fields fields
-		want   *ytypes.Schema
-	}{
-		// TODO: Add test cases.
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			oc := &OpenConfig{
-				transport: tt.fields.transport,
-				schema:    tt.fields.schema,
-			}
-			if got := oc.Schema(); !reflect.DeepEqual(got, tt.want) {
-				t.Errorf("Schema() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
-
-func TestOpenConfig_SetNode(t *testing.T) {
-	type fields struct {
-		transport Transport
-		schema    *ytypes.Schema
-	}
-	tests := []struct {
-		name   string
-		fields fields
-		want   func(schema *yang.Entry, root interface{}, path *gpb.Path, val interface{}, opts ...ytypes.SetNodeOpt) error
-	}{
-		// TODO: Add test cases.
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			oc := &OpenConfig{
-				transport: tt.fields.transport,
-				schema:    tt.fields.schema,
-			}
-			if got := oc.SetNode(); !reflect.DeepEqual(got, tt.want) {
-				t.Errorf("SetNode() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
-
-func Test_sbiStorage_Sbi(t *testing.T) {
-	type args struct {
-		name string
-	}
-	tests := []struct {
-		name    string
-		s       sbiStorage
-		args    args
-		want    SouthboundInterface
-		wantErr bool
-	}{
-		// TODO: Add test cases.
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			got, err := tt.s.Sbi(tt.args.name)
-			if (err != nil) != tt.wantErr {
-				t.Errorf("Sbi() error = %v, wantErr %v", err, tt.wantErr)
-				return
-			}
-			if !reflect.DeepEqual(got, tt.want) {
-				t.Errorf("Sbi() got = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}
-
-func Test_sbiStorage_add(t *testing.T) {
-	type args struct {
-		sbi SouthboundInterface
-	}
-	tests := []struct {
-		name    string
-		s       sbiStorage
-		args    args
-		wantErr bool
-	}{
-		// TODO: Add test cases.
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			if err := tt.s.add(tt.args.sbi); (err != nil) != tt.wantErr {
-				t.Errorf("add() error = %v, wantErr %v", err, tt.wantErr)
-			}
-		})
-	}
-}
-
-func Test_sbiStorage_delete(t *testing.T) {
-	type args struct {
-		name string
-	}
-	tests := []struct {
-		name    string
-		s       sbiStorage
-		args    args
-		wantErr bool
-	}{
-		// TODO: Add test cases.
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			if err := tt.s.delete(tt.args.name); (err != nil) != tt.wantErr {
-				t.Errorf("delete() error = %v, wantErr %v", err, tt.wantErr)
-			}
-		})
-	}
-}
-
-func Test_sbiStorage_exists(t *testing.T) {
-	type args struct {
-		name string
-	}
-	tests := []struct {
-		name string
-		s    sbiStorage
-		args args
-		want bool
-	}{
-		// TODO: Add test cases.
-	}
-	for _, tt := range tests {
-		t.Run(tt.name, func(t *testing.T) {
-			if got := tt.s.exists(tt.args.name); got != tt.want {
-				t.Errorf("exists() = %v, want %v", got, tt.want)
-			}
-		})
-	}
-}