diff --git a/sefht.geany b/sefht.geany
index 1960fc8f2f8853c73131d76d4a06f487b3ea3dd5..42ceb560eddcfb324d0358661ff55fafbb91c19e 100644
--- a/sefht.geany
+++ b/sefht.geany
@@ -28,7 +28,7 @@ long_line_behaviour=1
 long_line_column=72
 
 [files]
-current_page=53
+current_page=54
 FILE_NAME_0=139;None;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2FREADME;0;8
 FILE_NAME_1=134;None;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2F.gitignore;0;8
 FILE_NAME_2=1737;Sh;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fconfigure.ac;0;8
@@ -64,14 +64,14 @@ FILE_NAME_31=1111;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fp
 FILE_NAME_32=5802;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fvalidator_tag.c;0;8
 FILE_NAME_33=1148;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fvalidator_tag.h;0;8
 FILE_NAME_34=1124;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fvalidator_tag_data.h;0;8
-FILE_NAME_35=9882;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fvalidator_attr.c;0;8
+FILE_NAME_35=9830;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fvalidator_attr.c;0;8
 FILE_NAME_36=1627;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fvalidator_attr.h;0;8
 FILE_NAME_37=1099;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fvalidator_attr_data.h;0;8
 FILE_NAME_38=924;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fstatus.h;0;8
 FILE_NAME_39=18;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Flog.h;0;4
 FILE_NAME_40=20;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fmacro.h;0;8
 FILE_NAME_41=20;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fsefht.h;0;8
-FILE_NAME_42=3077;Make;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2FMakefile.am;0;8
+FILE_NAME_42=3259;Make;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2FMakefile.am;0;8
 FILE_NAME_43=218;Sh;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Fno_test.sh.in;0;8
 FILE_NAME_44=23;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_cms.c;0;8
 FILE_NAME_45=24;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_data.c;0;8
@@ -83,10 +83,11 @@ FILE_NAME_50=4221;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fp
 FILE_NAME_51=994;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_text_mark.c;0;8
 FILE_NAME_52=2447;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_validator.c;0;8
 FILE_NAME_53=3880;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_validator_tag.c;0;8
-FILE_NAME_54=536;None;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftodo.txt;0;8
-FILE_NAME_55=201;YAML;0;EUTF-8;0;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2F.gitlab-ci.yml;0;4
-FILE_NAME_56=71;Sh;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fgitlab-ci%2Fupload.sh.in;0;8
-FILE_NAME_57=806;Sh;0;EUTF-8;0;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fgitlab-ci%2Frelease.sh.in;0;4
+FILE_NAME_54=7652;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_validator_attr.c;0;8
+FILE_NAME_55=536;None;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftodo.txt;0;8
+FILE_NAME_56=201;YAML;0;EUTF-8;0;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2F.gitlab-ci.yml;0;4
+FILE_NAME_57=71;Sh;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fgitlab-ci%2Fupload.sh.in;0;8
+FILE_NAME_58=806;Sh;0;EUTF-8;0;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fgitlab-ci%2Frelease.sh.in;0;4
 
 [VTE]
 last_dir=/home/jonathan/Documents/projects/prgm/internet/web/SeFHT/tests
diff --git a/src/lib/sefht/validator_attr.c b/src/lib/sefht/validator_attr.c
index 0041186ef6dc0a9ca0bcf1bb0ae592242fd2e1ae..3cda4e329aa644949284b18400c6f8cb395732d7 100644
--- a/src/lib/sefht/validator_attr.c
+++ b/src/lib/sefht/validator_attr.c
@@ -441,6 +441,7 @@ SH_Validator_register_attr (struct SH_Validator * validator,
 	attr_id = get_attr_id_by_name (validator, attr, &index);
 	if (attr_id != ATTR_ERR)
 	{
+		set_success (status);
 		return attr_id;
 	}
 
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 0429773fcc4fb4851d1e96b9d4709702c0b8849b..86f7ab58946adb20df1d001c88a01931dbaf8c84 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -21,6 +21,7 @@ check_PROGRAMS += sefht_text_test
 check_PROGRAMS += sefht_text_mark_test
 check_PROGRAMS += sefht_validator_test
 check_PROGRAMS += sefht_validator_tag_test
+check_PROGRAMS += sefht_validator_attr_test
 
 XFAIL_TESTS =
 XFAIL_TESTS += sefht_fragment_test
@@ -94,3 +95,7 @@ sefht_validator_test_LDADD += $(LDADD)
 sefht_validator_tag_test_SOURCES = test_validator_tag.c
 sefht_validator_tag_test_LDADD =
 sefht_validator_tag_test_LDADD += $(LDADD)
+
+sefht_validator_attr_test_SOURCES = test_validator_attr.c
+sefht_validator_attr_test_LDADD =
+sefht_validator_attr_test_LDADD += $(LDADD)
diff --git a/tests/test_validator_attr.c b/tests/test_validator_attr.c
new file mode 100644
index 0000000000000000000000000000000000000000..5521536f3ec7e63bc5f68d6507f3c8e2f798dc75
--- /dev/null
+++ b/tests/test_validator_attr.c
@@ -0,0 +1,438 @@
+/*
+ * test_validator_attr.c
+ *
+ * Copyright 2023 Jonathan Schöbel <jonathan@xn--schbel-yxa.info>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ *
+ */
+
+
+#include <check.h>
+#include <math.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+/* lower SIZE_MAX as we try to reach it */
+#include <limits.h>
+#undef SIZE_MAX
+#define SIZE_MAX 10 * sizeof (struct attr_info)
+
+#include "macro.h"
+#include "status.h"
+
+
+/* C file is needed, because we want to override SIZE_MAX */
+#include "validator.c"
+
+
+START_TEST(test_validator_no_status)
+{
+	struct SH_Validator * validator;
+
+	validator = SH_Validator_new (NULL);
+	ck_assert_ptr_ne (NULL, validator);
+
+	ck_assert_int_eq (0, validator->attr_n);
+	ck_assert_int_eq (ATTR_ERR, validator->last_attr);
+
+	SH_Validator_free (validator);
+}
+END_TEST
+
+START_TEST(test_validator_with_status)
+{
+	struct SH_Status status;
+	struct SH_Validator * validator;
+
+	_status_preinit (status);
+	validator = SH_Validator_new (&status);
+	ck_assert_ptr_ne (NULL, validator);
+	ck_assert_int_eq (status.status, SUCCESS);
+
+	ck_assert_int_eq (0, validator->attr_n);
+	ck_assert_int_eq (ATTR_ERR, validator->last_attr);
+
+	SH_Validator_free (validator);
+}
+END_TEST
+
+START_TEST(test_validator_copy_no_status)
+{
+	struct SH_Validator * validator;
+	struct SH_Validator * copy;
+	Attr attr;
+
+	/* setup */
+	validator = SH_Validator_new_html5 (NULL);
+	ck_assert_ptr_ne (NULL, validator);
+
+	attr = SH_Validator_register_attr (validator, "id", NULL);
+	ck_assert_int_ne (ATTR_ERR, attr);
+
+	attr = SH_Validator_register_attr (validator, "lang", NULL);
+	ck_assert_int_ne (ATTR_ERR, attr);
+
+	/* test */
+	copy = SH_Validator_copy (validator, NULL);
+	ck_assert_ptr_ne (NULL, copy);
+
+	ck_assert_ptr_ne (NULL, copy->attrs);
+	ck_assert_ptr_ne (validator->attrs, copy->attrs);
+	ck_assert_int_eq (validator->attr_n, copy->attr_n);
+	ck_assert_int_eq (validator->last_attr, copy->last_attr);
+
+	#define TEST_INT(I) ck_assert_int_eq (validator->I, copy->I);
+	#define TEST_STR(S) ck_assert_ptr_ne (validator->S, copy->S);  \
+	                    ck_assert_str_eq (validator->S, copy->S);
+
+	for (size_t index = 0; index < copy->attr_n; index++)
+	{
+		TEST_INT(attrs[index].id)
+		TEST_STR(attrs[index].name)
+	}
+	#undef TEST_INT
+	#undef TEST_STR
+
+	SH_Validator_free (copy);
+	SH_Validator_free (validator);
+}
+END_TEST
+
+START_TEST(test_validator_copy_with_status)
+{
+	struct SH_Status status;
+	struct SH_Validator * validator;
+	struct SH_Validator * copy;
+	Attr attr;
+
+	/* setup */
+	validator = SH_Validator_new_html5 (NULL);
+	ck_assert_ptr_ne (NULL, validator);
+
+	attr = SH_Validator_register_attr (validator, "id", NULL);
+	ck_assert_int_ne (ATTR_ERR, attr);
+
+	attr = SH_Validator_register_attr (validator, "lang", NULL);
+	ck_assert_int_ne (ATTR_ERR, attr);
+
+	/* test */
+	_status_preinit (status);
+	copy = SH_Validator_copy (validator, &status);
+	ck_assert_ptr_ne (NULL, copy);
+	ck_assert_int_eq (status.status, SUCCESS);
+
+	ck_assert_ptr_ne (NULL, copy->attrs);
+	ck_assert_ptr_ne (validator->attrs, copy->attrs);
+	ck_assert_int_eq (validator->attr_n, copy->attr_n);
+	ck_assert_int_eq (validator->last_attr, copy->last_attr);
+
+	#define TEST_INT(I) ck_assert_int_eq (validator->I, copy->I);
+	#define TEST_STR(S) ck_assert_ptr_ne (validator->S, copy->S);  \
+	                    ck_assert_str_eq (validator->S, copy->S);
+
+	for (size_t index = 0; index < copy->attr_n; index++)
+	{
+		TEST_INT(attrs[index].id)
+		TEST_STR(attrs[index].name)
+	}
+	#undef TEST_INT
+	#undef TEST_STR
+
+	SH_Validator_free (copy);
+	SH_Validator_free (validator);
+}
+END_TEST
+
+START_TEST(test_validator_register_no_status)
+{
+	struct SH_Validator * validator;
+	const char * attr1 = "id";
+	const char * attr2 = "class";
+	const char * attr3 = "name";
+	const char * attr4 = "src";
+	const char * attr5 = "content";
+	char * attrN;
+	Tag attr;
+	Tag attr_;
+
+	/* setup */
+	validator = SH_Validator_new_html5 (NULL);
+	ck_assert_ptr_ne (NULL, validator);
+
+	/* test - register */
+	attr = SH_Validator_register_attr (validator, attr1, NULL);
+	ck_assert_int_eq (1, attr);
+
+	ck_assert_int_eq (validator->attr_n, 1);
+	ck_assert_int_eq (validator->last_attr, attr);
+
+	ck_assert_int_eq (validator->attrs[0].id, attr);
+	ck_assert_str_eq (validator->attrs[0].name, attr1);
+
+	/* test - duplicate registration */
+	attr_ = SH_Validator_register_attr (validator, attr1, NULL);
+	ck_assert_int_eq (attr_, attr);
+
+	ck_assert_int_eq (validator->attr_n, 1);
+	ck_assert_int_eq (validator->last_attr, attr);
+
+	ck_assert_int_eq (validator->attrs[0].id, attr);
+	ck_assert_str_eq (validator->attrs[0].name, attr1);
+
+	/* test - order */
+	attr = SH_Validator_register_attr (validator, attr3, NULL);
+	ck_assert_int_eq (attr, 2);
+
+	attr = SH_Validator_register_attr (validator, attr4, NULL);
+	ck_assert_int_eq (attr, 3);
+
+	attr = SH_Validator_register_attr (validator, attr5, NULL);
+	ck_assert_int_eq (attr, 4);
+
+	ck_assert_int_eq (validator->attr_n, 4);
+
+	ck_assert_str_eq (validator->attrs[0].name, attr5);
+	ck_assert_str_eq (validator->attrs[1].name, attr1);
+	ck_assert_str_eq (validator->attrs[2].name, attr3);
+	ck_assert_str_eq (validator->attrs[3].name, attr4);
+
+	/* test - overflow detection */
+	/* make method fail by filling with garbage until
+	 * upper boundary is reached */
+
+	/* ensure enough space  inside string*/
+	/* log10 +1 = number length */
+	/* +4 "attr" */
+	/* +1 '\0' */
+	/* = +5 */
+	attrN = calloc (((int) floor (log10 ((double) SIZE_MAX))) + 6,
+		       sizeof (char));
+
+	/* fill with garbage */
+	do
+	{
+		sprintf (attrN, "attr%zu", validator->attr_n);
+	}
+	while (ATTR_ERR != SH_Validator_register_attr (validator, attrN, NULL));
+
+	free (attrN);
+
+	/* test overflow #1 */
+	attr = SH_Validator_register_attr (validator, attr2, NULL);
+	ck_assert_int_eq (ATTR_ERR, attr);
+
+	ck_assert_int_eq (validator->attr_n, 10);
+
+	/* test overflow #2 */
+	validator->attr_n = 1;
+	validator->last_attr = ATTR_MAX;
+
+	attr = SH_Validator_register_attr (validator, attr2, NULL);
+	ck_assert_int_eq (ATTR_ERR, attr);
+
+	ck_assert_int_eq (validator->attr_n, 1);
+	ck_assert_int_eq (validator->last_attr, ATTR_MAX);
+
+	/* cleanup */
+	/* also free garbage created for overflow test */
+	validator->attr_n = 10;
+	SH_Validator_free (validator);
+}
+
+START_TEST(test_validator_register_with_status)
+{
+	struct SH_Status status;
+	struct SH_Validator * validator;
+	const char * attr1 = "id";
+	const char * attr2 = "class";
+	const char * attr3 = "name";
+	const char * attr4 = "src";
+	const char * attr5 = "content";
+	char * attrN;
+	Tag attr;
+	Tag attr_;
+
+	/* setup */
+	validator = SH_Validator_new_html5 (NULL);
+	ck_assert_ptr_ne (NULL, validator);
+
+	/* test - register */
+	_status_preinit (status);
+	attr = SH_Validator_register_attr (validator, attr1, &status);
+	ck_assert_int_eq (1, attr);
+	ck_assert_int_eq (SUCCESS, status.status);
+
+	ck_assert_int_eq (validator->attr_n, 1);
+	ck_assert_int_eq (validator->last_attr, attr);
+
+	ck_assert_int_eq (validator->attrs[0].id, attr);
+	ck_assert_str_eq (validator->attrs[0].name, attr1);
+
+	/* test - duplicate registration */
+	_status_preinit (status);
+	attr_ = SH_Validator_register_attr (validator, attr1, &status);
+	ck_assert_int_eq (attr_, attr);
+	ck_assert_int_eq (SUCCESS, status.status);
+
+	ck_assert_int_eq (validator->attr_n, 1);
+	ck_assert_int_eq (validator->last_attr, attr);
+
+	ck_assert_int_eq (validator->attrs[0].id, attr);
+	ck_assert_str_eq (validator->attrs[0].name, attr1);
+
+	/* test - order */
+	_status_preinit (status);
+	attr = SH_Validator_register_attr (validator, attr3, &status);
+	ck_assert_int_eq (attr, 2);
+	ck_assert_int_eq (status.status, SUCCESS);
+
+	_status_preinit (status);
+	attr = SH_Validator_register_attr (validator, attr4, &status);
+	ck_assert_int_eq (attr, 3);
+	ck_assert_int_eq (status.status, SUCCESS);
+
+	_status_preinit (status);
+	attr = SH_Validator_register_attr (validator, attr5, &status);
+	ck_assert_int_eq (attr, 4);
+	ck_assert_int_eq (status.status, SUCCESS);
+
+	ck_assert_int_eq (validator->attr_n, 4);
+
+	ck_assert_str_eq (validator->attrs[0].name, attr5);
+	ck_assert_str_eq (validator->attrs[1].name, attr1);
+	ck_assert_str_eq (validator->attrs[2].name, attr3);
+	ck_assert_str_eq (validator->attrs[3].name, attr4);
+
+	/* test - overflow detection */
+	/* make method fail by filling with garbage until
+	 * upper boundary is reached */
+
+	/* ensure enough space  inside string*/
+	/* log10 +1 = number length */
+	/* +4 "attr" */
+	/* +1 '\0' */
+	/* = +5 */
+	attrN = calloc (((int) floor (log10 ((double) SIZE_MAX))) + 6,
+		       sizeof (char));
+
+	/* fill with garbage */
+	do
+	{
+		sprintf (attrN, "attr%zu", validator->attr_n);
+	}
+	while (ATTR_ERR != SH_Validator_register_attr (validator, attrN, NULL));
+
+	free (attrN);
+
+	/* test overflow #1 */
+	_status_preinit (status);
+	attr = SH_Validator_register_attr (validator, attr2, &status);
+	ck_assert_int_eq (ATTR_ERR, attr);
+	ck_assert_int_eq (E_DOMAIN, status.status);
+
+	ck_assert_int_eq (validator->attr_n, 10);
+
+	/* test overflow #2 */
+	validator->attr_n = 1;
+	validator->last_attr = ATTR_MAX;
+
+	_status_preinit (status);
+	attr = SH_Validator_register_attr (validator, attr2, &status);
+	ck_assert_int_eq (ATTR_ERR, attr);
+	ck_assert_int_eq (E_DOMAIN, status.status);
+
+	ck_assert_int_eq (validator->attr_n, 1);
+	ck_assert_int_eq (validator->last_attr, ATTR_MAX);
+
+	/* cleanup */
+	/* also free garbage created for overflow test */
+	validator->attr_n = 10;
+	SH_Validator_free (validator);
+}
+
+START_TEST(test_validator_check)
+{
+	struct SH_Validator * validator;
+	const char * attr1  = "id";
+	const char * attr2  = "id";
+	const char * attr3  = "class";
+	Tag attr;
+	bool result;
+
+	/* setup */
+	validator = SH_Validator_new (NULL);
+	ck_assert_ptr_ne (NULL, validator);
+
+	attr = SH_Validator_register_attr (validator, attr1, NULL);
+	ck_assert_int_ne (ATTR_ERR, attr);
+
+	/* test */
+	result = SH_Validator_check_attr (validator, attr1);
+	ck_assert_int_eq (TRUE, result);
+
+	result = SH_Validator_check_attr (validator, attr2);
+	ck_assert_int_eq (TRUE, result);
+
+	result = SH_Validator_check_attr (validator, attr3);
+	ck_assert_int_eq (FALSE, result);
+
+	/* cleanup */
+	SH_Validator_free (validator);
+}
+END_TEST
+
+Suite * test_suite (void)
+{
+	Suite *s;
+	TCase *tc_core;
+
+	s = suite_create ("Testsuite SeFHT Validator Tag");
+
+	/* Core test case */
+	tc_core = tcase_create ("Core");
+
+	tcase_add_test (tc_core, test_validator_no_status);
+	tcase_add_test (tc_core, test_validator_with_status);
+	tcase_add_test (tc_core, test_validator_copy_no_status);
+	tcase_add_test (tc_core, test_validator_copy_with_status);
+	tcase_add_test (tc_core, test_validator_register_no_status);
+	tcase_add_test (tc_core, test_validator_register_with_status);
+	tcase_add_test (tc_core, test_validator_check);
+	suite_add_tcase (s, tc_core);
+
+	return s;
+}
+
+int main (void)
+{
+	int number_failed;
+	Suite *s;
+	SRunner *sr;
+
+	s = test_suite ();
+	sr = srunner_create (s);
+
+	srunner_run_all (sr, CK_NORMAL);
+	number_failed = srunner_ntests_failed (sr);
+	srunner_free (sr);
+
+	return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+}
+