diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 41304ba6681cb419bf6803577655af6454a3d724..4c4b1b512a54339296ef77933f4f0fc76dd76311 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -7,9 +7,10 @@ include:
       - '/includes/include.drupalci.workflows.yml'
 
 variables:
-  _CSPELL_IGNORE_PATHS: './config/*, ./css/*, ./icons/*, ./images/*, ./README.md'
+  _CSPELL_IGNORE_PATHS: './config/*, ./css/*, ./icons/*, ./images/*, ./tests/*, ./README.md'
   _CSPELL_WORDS: 'langname, grumphp, perc, addtoany'
   OPT_IN_TEST_NEXT_MAJOR: 0
+  _PHPUNIT_CONCURRENT: '1'
 
 composer:
   variables:
diff --git a/config/install/filter.format.full_html.yml b/config/install/filter.format.full_html.yml
new file mode 100644
index 0000000000000000000000000000000000000000..07e5c67f00a58f79dff8e884899a78cd929e5ca8
--- /dev/null
+++ b/config/install/filter.format.full_html.yml
@@ -0,0 +1,39 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - editor
+name: 'Full HTML'
+format: full_html
+weight: 2
+filters:
+  editor_file_reference:
+    id: editor_file_reference
+    provider: editor
+    status: true
+    weight: 11
+    settings: {  }
+  filter_align:
+    id: filter_align
+    provider: filter
+    status: true
+    weight: 8
+    settings: {  }
+  filter_caption:
+    id: filter_caption
+    provider: filter
+    status: true
+    weight: 9
+    settings: {  }
+  filter_htmlcorrector:
+    id: filter_htmlcorrector
+    provider: filter
+    status: true
+    weight: 10
+    settings: {  }
+  filter_image_lazy_load:
+    id: filter_image_lazy_load
+    provider: filter
+    status: true
+    weight: 15
+    settings: {  }
diff --git a/config/schema/quiz_maker.schema.yml b/config/schema/quiz_maker.schema.yml
index 9b75373640af461534e3a3ae9415048f854c7b87..d3ed7560334a21fd1c754a4f50458f9a8bb51c1d 100644
--- a/config/schema/quiz_maker.schema.yml
+++ b/config/schema/quiz_maker.schema.yml
@@ -1,4 +1,4 @@
-field.formatter.settings.question_response:
+field.formatter.settings.question_response_formatter:
   type: mapping
   label: Question Response formatter formatter settings
   mapping:
@@ -27,3 +27,78 @@ quiz_maker.quiz_result_type.*:
     workflow:
       type: string
       label: 'Workflow'
+
+quiz_maker.question_answer_type.*:
+  type: config_entity
+  label: 'Question Answer Type'
+  mapping:
+    id:
+      type: string
+      label: 'Machine Name'
+      description: 'The machine-readable ID for the question answer type.'
+    label:
+      type: string
+      label: 'Human-readable Name'
+      description: 'The human-readable name for the question answer type.'
+    plugin:
+      type: string
+      label: 'Plugin ID'
+      description: 'The plugin ID associated with this question answer type.'
+    uuid:
+      type: string
+      label: 'UUID'
+      description: 'The universally unique identifier (UUID) for this question answer type.'
+
+quiz_maker.question_response_type.*:
+  type: config_entity
+  label: 'Question Response Type'
+  mapping:
+    id:
+      type: string
+      label: 'Machine Name'
+      description: 'The machine-readable ID for the answer response type.'
+    label:
+      type: string
+      label: 'Human-readable Name'
+      description: 'The human-readable name for the answer response type.'
+    plugin:
+      type: string
+      label: 'Plugin ID'
+      description: 'The plugin ID associated with this answer response type.'
+    uuid:
+      type: string
+      label: 'UUID'
+      description: 'The universally unique identifier (UUID) for this answer response type.'
+
+quiz_maker.quiz_type.*:
+  type: config_entity
+  label: 'Quiz type config'
+  mapping:
+    id:
+      type: string
+      label: 'ID'
+    label:
+      type: label
+      label: 'Label'
+    uuid:
+      type: string
+
+quiz_maker.question_type.*:
+  type: config_entity
+  label: 'Question type config'
+  mapping:
+    id:
+      type: string
+      label: 'ID'
+    label:
+      type: label
+      label: 'Label'
+    uuid:
+      type: string
+    plugin:
+      type: string
+    answer_type:
+      type: string
+    response_type:
+      type: string
+
diff --git a/quiz_maker.info.yml b/quiz_maker.info.yml
index 2191c8c61110d19109b8ee5eb6891b2204f32a20..e1339aab1bb3d6ac8d992c9487324efc9743ea3f 100644
--- a/quiz_maker.info.yml
+++ b/quiz_maker.info.yml
@@ -16,3 +16,4 @@ dependencies:
   - paragraphs:paragraphs
   - addtoany:addtoany
   - update_helper:update_helper
+  - drupal:taxonomy
diff --git a/quiz_maker.module b/quiz_maker.module
index 32ef930fbaaf0ded74e7e4a8b9a871ee2fb8ca05..019db1b8e4cd10e0075986bda3bfa07fbc5547ae 100644
--- a/quiz_maker.module
+++ b/quiz_maker.module
@@ -21,6 +21,8 @@ use Drupal\quiz_maker\Entity\QuestionAnswer;
 use Drupal\quiz_maker\Entity\QuestionType;
 use Drupal\quiz_maker\Entity\QuizResultFeedbackParagraph;
 use Drupal\quiz_maker\Entity\QuizResultType;
+use Drupal\quiz_maker\Plugin\QuizMaker\QuestionAnswerPluginInterface;
+use Drupal\quiz_maker\Plugin\QuizMaker\QuestionPluginInterface;
 use Drupal\quiz_maker\QuizInterface;
 use Drupal\quiz_maker\QuizResultInterface;
 use Drupal\taxonomy\TermInterface;
@@ -465,7 +467,7 @@ function quiz_maker_entity_presave(EntityInterface $entity): void {
   if ($entity instanceof Question) {
     $question_type = QuestionType::load($entity->bundle());
     $question_instance = $entity->getPluginInstance();
-    if (!$question_instance->getAnswers()) {
+    if ($question_instance instanceof QuestionPluginInterface && !$question_instance->getAnswers()) {
       $bundle = $question_type->getAnswerType();
       $default_answers_data = $entity->getDefaultAnswersData();
       foreach ($default_answers_data as $answer_data) {
@@ -500,6 +502,10 @@ function quiz_maker_entity_presave(EntityInterface $entity): void {
 
   if ($entity instanceof QuestionAnswer) {
     $answer_instance = $entity->getPluginInstance();
+    if (!$answer_instance instanceof QuestionAnswerPluginInterface) {
+      return;
+    }
+
     if ($answer_instance->isAlwaysCorrect()) {
       $answer_instance->setCorrect(TRUE);
     }
@@ -609,6 +615,9 @@ function quiz_maker_entity_base_field_info_alter(&$fields, EntityTypeInterface $
       ->setDisplayOptions('form', [
         'type' => 'text_textarea',
         'weight' => 10,
+        'settings' => [
+          'rows' => 5,
+        ],
       ])
       ->setDisplayConfigurable('form', TRUE)
       ->setDisplayOptions('view', [
diff --git a/src/Entity/Question.php b/src/Entity/Question.php
index 50cdbfefb5cb86200653253a3488a72cf6712f8a..9ed5fdc1a9c01f58ce8c941ee057bcf08963fd45 100644
--- a/src/Entity/Question.php
+++ b/src/Entity/Question.php
@@ -280,7 +280,7 @@ class Question extends RevisionableContentEntityBase implements QuestionInterfac
    * {@inheritDoc}
    */
   public function getQuestion(): ?string {
-    return $this->getPluginInstance()->getQuestion();
+    return $this->getPluginInstance()?->getQuestion();
   }
 
   /**
@@ -300,15 +300,15 @@ class Question extends RevisionableContentEntityBase implements QuestionInterfac
   /**
    * {@inheritDoc}
    */
-  public function getMaxScore(): int {
-    return $this->getPluginInstance()->getMaxScore();
+  public function getMaxScore(): ?int {
+    return $this->getPluginInstance()?->getMaxScore();
   }
 
   /**
    * {@inheritDoc}
    */
   public function getTag(): ?TermInterface {
-    return $this->getPluginInstance()->getTag();
+    return $this->getPluginInstance()?->getTag();
   }
 
   /**
diff --git a/src/Entity/Quiz.php b/src/Entity/Quiz.php
index 8e2c74ec1fdfe0a78e9c9ed5c986ceb98910039c..6e31743e6a2b279fbda45bf6ae27d0d7add9e451 100644
--- a/src/Entity/Quiz.php
+++ b/src/Entity/Quiz.php
@@ -227,7 +227,11 @@ class Quiz extends RevisionableContentEntityBase implements QuizInterface {
       ])
       ->setDisplayConfigurable('form', TRUE)
       ->setDisplayOptions('view', [
+        'type' => 'daterange_default',
         'weight' => 5,
+        'settings' => [
+          'separator' => '-',
+        ],
       ])
       ->setDisplayConfigurable('view', TRUE);
 
@@ -356,7 +360,11 @@ class Quiz extends RevisionableContentEntityBase implements QuizInterface {
       ])
       ->setDisplayConfigurable('form', TRUE)
       ->setDisplayOptions('view', [
+        'type' => 'time_limit',
         'weight' => 6,
+        'settings' => [
+          'time_format' => 'H:i:s',
+        ],
       ])
       ->setDisplayConfigurable('view', TRUE);
 
diff --git a/src/Entity/QuizResult.php b/src/Entity/QuizResult.php
index 3a1044d89add94d0d414e92b9de32d85e696ecad..f19aeef5e2a064e954d9fd5b62859dc5bdec1a90 100644
--- a/src/Entity/QuizResult.php
+++ b/src/Entity/QuizResult.php
@@ -160,6 +160,9 @@ class QuizResult extends ContentEntityBase implements QuizResultInterface {
       ->setDisplayOptions('view', [
         'type' => 'question_response_formatter',
         'weight' => 6,
+        'settings' => [
+          'list_style' => 'Number with bracket',
+        ],
       ])
       ->setDisplayConfigurable('view', TRUE);
 
@@ -328,11 +331,11 @@ class QuizResult extends ContentEntityBase implements QuizResultInterface {
    * @param \Drupal\quiz_maker\QuizResultInterface $quiz_result
    *   The order.
    *
-   * @return string
+   * @return ?string
    *   The workflow ID.
    */
-  public static function getWorkflowId(QuizResultInterface $quiz_result): string {
-    return QuizResultType::load($quiz_result->bundle())->getWorkflowId();
+  public static function getWorkflowId(QuizResultInterface $quiz_result): ?string {
+    return QuizResultType::load($quiz_result->bundle())?->getWorkflowId();
   }
 
   /**
diff --git a/src/Plugin/Field/FieldFormatter/QuestionCountFormatter.php b/src/Plugin/Field/FieldFormatter/QuestionCountFormatter.php
index 8cdcd268ce37b7f3b66c99292c923f534319ab59..5847f87436d7d1c9a3400f4edf86a542b14a3a9e 100644
--- a/src/Plugin/Field/FieldFormatter/QuestionCountFormatter.php
+++ b/src/Plugin/Field/FieldFormatter/QuestionCountFormatter.php
@@ -15,7 +15,7 @@ use Drupal\Core\Field\FormatterBase;
  *   field_types = {"entity_reference", "entity_reference_revisions"},
  * )
  */
-final class QuestionCountFormatter extends FormatterBase {
+class QuestionCountFormatter extends FormatterBase {
 
   /**
    * {@inheritdoc}
diff --git a/src/Plugin/Field/FieldFormatter/QuestionResponseFormatter.php b/src/Plugin/Field/FieldFormatter/QuestionResponseFormatter.php
index 5be2436f6453c6d5932ec5916ed073c32a4a4314..0ad1ee6dab27285b701dda7173598b3c3e04905b 100644
--- a/src/Plugin/Field/FieldFormatter/QuestionResponseFormatter.php
+++ b/src/Plugin/Field/FieldFormatter/QuestionResponseFormatter.php
@@ -19,7 +19,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
  *   field_types = {"entity_reference", "entity_reference_revisions"},
  * )
  */
-final class QuestionResponseFormatter extends FormatterBase {
+class QuestionResponseFormatter extends FormatterBase {
 
   /**
    * Constructs a new QuestionResponseFormatter object.
diff --git a/src/Plugin/Field/FieldFormatter/ScoreFieldFormatter.php b/src/Plugin/Field/FieldFormatter/ScoreFieldFormatter.php
index 62910540487057820f5cdf422f00455360010c14..d1d43dd46e30814725465416d0c3cb6d61a9aaac 100644
--- a/src/Plugin/Field/FieldFormatter/ScoreFieldFormatter.php
+++ b/src/Plugin/Field/FieldFormatter/ScoreFieldFormatter.php
@@ -15,7 +15,7 @@ use Drupal\Core\Form\FormStateInterface;
  *   field_types = {"integer"},
  * )
  */
-final class ScoreFieldFormatter extends FormatterBase {
+class ScoreFieldFormatter extends FormatterBase {
 
   /**
    * {@inheritdoc}
diff --git a/src/Plugin/Field/FieldFormatter/TimeLimitFormatter.php b/src/Plugin/Field/FieldFormatter/TimeLimitFormatter.php
index 4cc2acf4fd97da47388dffd034a42998fc053a21..dd770023e9e813ab4f3c8551d59939e4a07c73a7 100644
--- a/src/Plugin/Field/FieldFormatter/TimeLimitFormatter.php
+++ b/src/Plugin/Field/FieldFormatter/TimeLimitFormatter.php
@@ -19,7 +19,7 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
  *   field_types = {"integer"},
  * )
  */
-final class TimeLimitFormatter extends FormatterBase {
+class TimeLimitFormatter extends FormatterBase {
 
   /**
    * Constructs a new TimeLimitFormatter object.
diff --git a/src/QuestionInterface.php b/src/QuestionInterface.php
index fc2232ba2bf01ee3af04444cd9cede30cc7b7d1d..6d14353e44217f934e4e400b44c8d32c2caf8f6a 100644
--- a/src/QuestionInterface.php
+++ b/src/QuestionInterface.php
@@ -119,10 +119,10 @@ interface QuestionInterface {
   /**
    * Get max score.
    *
-   * @return int
+   * @return ?int
    *   The score.
    */
-  public function getMaxScore(): int;
+  public function getMaxScore(): ?int;
 
   /**
    * Get default answers.
diff --git a/tests/src/Functional/QuizAnonymousTest.php b/tests/src/Functional/QuizAnonymousTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..83343bda3c77d10acb5a37270f6d9d37fa9bffb8
--- /dev/null
+++ b/tests/src/Functional/QuizAnonymousTest.php
@@ -0,0 +1,158 @@
+<?php
+
+namespace Drupal\Tests\quiz_maker\Functional;
+
+use Drupal\Core\StringTranslation\StringTranslationTrait;
+use Drupal\quiz_maker\Entity\Question;
+use Drupal\quiz_maker\Entity\QuestionAnswer;
+use Drupal\quiz_maker\Entity\Quiz;
+
+/**
+ * Test basic anonymous quiz taking.
+ *
+ * @group quiz_maker
+ */
+class QuizAnonymousTest extends QuizTestBase {
+
+  use StringTranslationTrait;
+
+  /**
+   * Test taking quiz by anonymous user.
+   */
+  public function testAnonymousQuizTake() {
+    // Login as our privileged user.
+    $this->drupalLogin($this->admin);
+    // Create quiz.
+    $multiple_answer1 = QuestionAnswer::create([
+      'bundle' => 'multiple_choice_answer',
+      'label' => 'Answer 1',
+      'answer' => 'Answer 1',
+      'is_correct' => TRUE,
+    ]);
+
+    $multiple_answer1->save();
+
+    $multiple_answer2 = QuestionAnswer::create([
+      'bundle' => 'multiple_choice_answer',
+      'label' => 'Answer 2',
+      'answer' => 'Answer 2',
+      'is_correct' => TRUE,
+    ]);
+
+    $multiple_answer2->save();
+
+    $multiple_answer3 = QuestionAnswer::create([
+      'bundle' => 'multiple_choice_answer',
+      'label' => 'Answer 3',
+      'answer' => 'Answer 3',
+      'is_correct' => FALSE,
+    ]);
+
+    $multiple_answer3->save();
+
+    $multiple_answer4 = QuestionAnswer::create([
+      'bundle' => 'multiple_choice_answer',
+      'label' => 'Answer 4',
+      'answer' => 'Answer 4',
+      'is_correct' => FALSE,
+    ]);
+
+    $multiple_answer4->save();
+
+    $multiple_question1 = Question::create([
+      'bundle' => 'multiple_choice_question',
+      'label' => 'Multiple Choice Question',
+      'description' => 'Multiple Choice Question 1',
+      'question' => 'Multiple Choice Question 1?',
+      'response_type' => 'multiple_choice_response',
+      'max_score' => 100,
+      'answers' => [$multiple_answer1, $multiple_answer2, $multiple_answer3, $multiple_answer4],
+    ]);
+
+    $multiple_question1->save();
+
+    $multiple_answer5 = QuestionAnswer::create([
+      'bundle' => 'multiple_choice_answer',
+      'label' => 'Answer 5',
+      'answer' => 'Answer 5',
+      'is_correct' => TRUE,
+    ]);
+
+    $multiple_answer5->save();
+
+    $multiple_answer6 = QuestionAnswer::create([
+      'bundle' => 'multiple_choice_answer',
+      'label' => 'Answer 6',
+      'answer' => 'Answer 6',
+      'is_correct' => TRUE,
+    ]);
+
+    $multiple_answer6->save();
+
+    $multiple_answer7 = QuestionAnswer::create([
+      'bundle' => 'multiple_choice_answer',
+      'label' => 'Answer 7',
+      'answer' => 'Answer 7',
+      'is_correct' => TRUE,
+    ]);
+
+    $multiple_answer7->save();
+
+    $multiple_answer8 = QuestionAnswer::create([
+      'bundle' => 'multiple_choice_answer',
+      'label' => 'Answer 8',
+      'answer' => 'Answer 8',
+      'is_correct' => TRUE,
+    ]);
+
+    $multiple_answer8->save();
+
+    $multiple_question2 = Question::create([
+      'bundle' => 'multiple_choice_question',
+      'label' => 'Multiple Choice Question',
+      'description' => 'Multiple Choice Question 2',
+      'question' => 'Multiple Choice Question 2?',
+      'response_type' => 'multiple_choice_response',
+      'max_score' => 100,
+      'answers' => [$multiple_answer5, $multiple_answer6, $multiple_answer7, $multiple_answer8],
+    ]);
+
+    $multiple_question1->save();
+
+    $quiz = Quiz::create([
+      'bundle' => 'standard',
+      'label' => 'Test quiz',
+      'description' => 'Empty quiz',
+      'result_type' => 'standard',
+      'attempts' => 5,
+      'questions' => [$multiple_question1, $multiple_question2],
+    ]);
+
+    $quiz->save();
+
+    // Logout.
+    $this->drupalLogout();
+
+    // Take the quiz, make sure we can view and click the link to start.
+    $this->drupalGet("quiz/{$quiz->id()}");
+    $this->clickLink('Take quiz');
+    $this->drupalGet("quiz/{$quiz->id()}/take");
+
+    $this->submitForm([
+      "_{$multiple_question1->id()}[{$multiple_answer1->id()}]" => '1',
+    ], (string) $this->t('Next'));
+    $this->submitForm([
+      "_{$multiple_question2->id()}[{$multiple_answer5->id()}]" => '1',
+    ], (string) $this->t('Finish'));
+
+    $this->assertSession()->pageTextContains($this->t('Result of "Test quiz"'));
+    $this->assertSession()->elementContains('css', '.field--name-score',  '0%');
+    $this->assertSession()->elementContains('css', '.field--name-passed',  'No');
+    $this->assertSession()->pageTextContains('Question response');
+    $this->assertSession()->pageTextContains('Multiple Choice Question 1');
+    $this->assertSession()->pageTextContains('Multiple Choice Question 2');
+    $this->assertSession()->pageTextContains('Take quiz again');
+    $this->assertSession()->pageTextContains('Go back to quiz');
+  }
+
+}
diff --git a/tests/src/Functional/QuizTestBase.php b/tests/src/Functional/QuizTestBase.php
new file mode 100644
index 0000000000000000000000000000000000000000..826bb2be5f8e14d374bcd6dc099cacc402c843c2
--- /dev/null
+++ b/tests/src/Functional/QuizTestBase.php
@@ -0,0 +1,86 @@
+<?php
+
+namespace Drupal\Tests\quiz_maker\Functional;
+
+use Drupal\Tests\BrowserTestBase;
+use Drupal\Tests\quiz_maker\Traits\QuizCreateTrait;
+
+/**
+ * Base test class for Quiz.
+ */
+class QuizTestBase extends BrowserTestBase {
+
+  use QuizCreateTrait;
+
+  /**
+   * Set to TRUE to strict check all configuration saved.
+   *
+   * @var bool
+   * @see ConfigSchemaChecker
+   *
+   * @todo Remove once there is 8.x-3.0-alpha6 which fixes a schema issue.
+   */
+  protected $strictConfigSchema = FALSE;
+
+  /**
+   * The theme to install as the default for testing.
+   *
+   * Defaults to the install profile's default theme, if it specifies any.
+   *
+   * @var string
+   */
+  protected $defaultTheme = 'claro';
+
+  /**
+   * Modules to install.
+   *
+   * @var array
+   */
+  protected static $modules = ['quiz_maker'];
+
+  /**
+   * Normal User account.
+   *
+   * @var \Drupal\user\Entity\User
+   */
+  protected $user;
+
+  /**
+   * Administration user account.
+   *
+   * @var \Drupal\user\Entity\User
+   */
+  protected $admin;
+
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setUp($admin_permissions = [], $user_permissions = []): void {
+    parent::setUp();
+
+    $admin_permissions = array_merge($admin_permissions, [
+      'administer question types',
+      'administer quiz types',
+      'administer question_answer types',
+      'administer quiz_result types',
+      'administer question_response types',
+      'administer quiz_result',
+    ]);
+
+    $user_permissions = array_merge($user_permissions, [
+      'view all question revisions',
+      'view all quiz revisions',
+      'view question',
+      'view question revision',
+      'view quiz',
+      'view quiz revision',
+      'view quiz_result',
+      'take quiz',
+    ]);
+
+    $this->admin = $this->drupalCreateUser(array_unique($admin_permissions));
+    $this->user = $this->drupalCreateUser(array_unique($user_permissions));
+  }
+
+}
diff --git a/tests/src/Kernel/QuestionAnswerKernelTest.php b/tests/src/Kernel/QuestionAnswerKernelTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..67676aeea9bb34b551428759c539c627eb15d902
--- /dev/null
+++ b/tests/src/Kernel/QuestionAnswerKernelTest.php
@@ -0,0 +1,212 @@
+<?php
+
+namespace Drupal\Tests\quiz_maker\Kernel;
+
+use Drupal\quiz_maker\Entity\QuestionAnswer;
+use Drupal\Tests\quiz_maker\Traits\QuestionAnswerCreateTrait;
+
+/**
+ * Tests creation of Quiz Question Answers.
+ *
+ * @group quiz_maker
+ */
+class QuestionAnswerKernelTest extends QuizKernelTestBase {
+
+  use QuestionAnswerCreateTrait;
+
+  /**
+   * Tests the creation boolean Answer.
+   */
+  public function testBooleanAnswerCreate() {
+    $answer = $this->createBooleanAnswer();
+
+    $this->assertEquals('Boolean answer', $answer->label());
+    $this->assertEquals('boolean_answer', $answer->bundle());
+    $this->assertEquals('Boolean answer', $answer->get('answer')->value);
+    $this->assertEquals(FALSE, $answer->get('is_correct')->value);
+  }
+
+  /**
+   * Tests the updating boolean Answer.
+   */
+  public function testBooleanAnswerUpdate() {
+    $answer = $this->createBooleanAnswer();
+
+    $answer->set('answer', 'Updated Boolean Answer');
+    $answer->set('is_correct', TRUE);
+
+    $this->assertEquals('Updated Boolean Answer', $answer->get('answer')->value);
+    $this->assertEquals(TRUE, $answer->get('is_correct')->value);
+  }
+
+  /**
+   * Tests the deleting boolean Answer.
+   */
+  public function testBooleanAnswerDelete() {
+    $answer = $this->createBooleanAnswer();
+
+    $answer_id = $answer->id();
+    $answer->delete();
+
+    // Assert that the quiz no longer exists in the database.
+    $deleted_answer = QuestionAnswer::load($answer_id);
+    $this->assertNull($deleted_answer);
+  }
+
+  /**
+   * Tests the creation direct Answer.
+   */
+  public function testDirectAnswerCreate() {
+    $answer = $this->createDirectAnswer();
+
+    $this->assertEquals('Direct answer', $answer->label());
+    $this->assertEquals('direct_answer', $answer->bundle());
+    $this->assertEquals('Direct answer', $answer->get('answer')->value);
+    $this->assertEquals(FALSE, $answer->get('is_correct')->value);
+  }
+
+  /**
+   * Tests the updating direct Answer.
+   */
+  public function testDirectAnswerUpdate() {
+    $answer = $this->createDirectAnswer();
+
+    $answer->set('answer', 'Updated Direct Answer');
+    $answer->set('is_correct', TRUE);
+
+    $this->assertEquals('Updated Direct Answer', $answer->get('answer')->value);
+    $this->assertEquals(TRUE, $answer->get('is_correct')->value);
+  }
+
+  /**
+   * Tests the deleting direct Answer.
+   */
+  public function testDirectAnswerDelete() {
+    $answer = $this->createDirectAnswer();
+
+    $answer_id = $answer->id();
+    $answer->delete();
+
+    // Assert that the quiz no longer exists in the database.
+    $deleted_answer = QuestionAnswer::load($answer_id);
+    $this->assertNull($deleted_answer);
+  }
+
+  /**
+   * Tests the creation of Matching Answer.
+   */
+  public function testMatchingAnswerCreate() {
+    $answer = $this->createMatchingAnswer();
+
+    $this->assertEquals('Matching answer', $answer->label());
+    $this->assertEquals('matching_answer', $answer->bundle());
+    $this->assertEquals('Matching answer', $answer->get('answer')->value);
+    $this->assertEquals(FALSE, $answer->get('is_correct')->value);
+  }
+
+  /**
+   * Tests the updating of Matching Answer.
+   */
+  public function testMatchingAnswerUpdate() {
+    $answer = $this->createMatchingAnswer();
+
+    $answer->set('answer', 'Updated Matching Answer');
+    $answer->set('is_correct', TRUE);
+
+    $this->assertEquals('Updated Matching Answer', $answer->get('answer')->value);
+    $this->assertEquals(TRUE, $answer->get('is_correct')->value);
+  }
+
+  /**
+   * Tests the deleting of Matching Answer.
+   */
+  public function testMatchingAnswerDelete() {
+    $answer = $this->createMatchingAnswer();
+
+    $answer_id = $answer->id();
+    $answer->delete();
+
+    // Assert that the matching answer no longer exists in the database.
+    $deleted_answer = QuestionAnswer::load($answer_id);
+    $this->assertNull($deleted_answer);
+  }
+
+  /**
+   * Tests the creation of Multiple Choice Answer.
+   */
+  public function testMultipleChoiceAnswerCreate() {
+    $answer = $this->createMultipleChoiceAnswer();
+
+    $this->assertEquals('Multiple Choice answer', $answer->label());
+    $this->assertEquals('multiple_choice_answer', $answer->bundle());
+    $this->assertEquals('Multiple Choice answer', $answer->get('answer')->value);
+    $this->assertEquals(FALSE, $answer->get('is_correct')->value);
+  }
+
+  /**
+   * Tests the updating of Multiple Choice Answer.
+   */
+  public function testMultipleChoiceAnswerUpdate() {
+    $answer = $this->createMultipleChoiceAnswer();
+
+    $answer->set('answer', 'Updated Multiple Choice Answer');
+    $answer->set('is_correct', TRUE);
+
+    $this->assertEquals('Updated Multiple Choice Answer', $answer->get('answer')->value);
+    $this->assertEquals(TRUE, $answer->get('is_correct')->value);
+  }
+
+  /**
+   * Tests the deleting of Multiple Choice Answer.
+   */
+  public function testMultipleChoiceAnswerDelete() {
+    $answer = $this->createMultipleChoiceAnswer();
+
+    $answer_id = $answer->id();
+    $answer->delete();
+
+    // Assert that the multiple choice answer no longer exists in the database.
+    $deleted_answer = QuestionAnswer::load($answer_id);
+    $this->assertNull($deleted_answer);
+  }
+
+  /**
+   * Tests the creation of Single Choice Answer.
+   */
+  public function testSingleChoiceAnswerCreate() {
+    $answer = $this->createSingleChoiceAnswer();
+
+    $this->assertEquals('Single Choice answer', $answer->label());
+    $this->assertEquals('single_choice_answer', $answer->bundle());
+    $this->assertEquals('Single Choice answer', $answer->get('answer')->value);
+    $this->assertEquals(FALSE, $answer->get('is_correct')->value);
+  }
+
+  /**
+   * Tests the updating of Single Choice Answer.
+   */
+  public function testSingleChoiceAnswerUpdate() {
+    $answer = $this->createSingleChoiceAnswer();
+
+    $answer->set('answer', 'Updated Single Choice Answer');
+    $answer->set('is_correct', TRUE);
+
+    $this->assertEquals('Updated Single Choice Answer', $answer->get('answer')->value);
+    $this->assertEquals(TRUE, $answer->get('is_correct')->value);
+  }
+
+  /**
+   * Tests the deleting of Single Choice Answer.
+   */
+  public function testSingleChoiceAnswerDelete() {
+    $answer = $this->createSingleChoiceAnswer();
+
+    $answer_id = $answer->id();
+    $answer->delete();
+
+    // Assert that the single choice answer no longer exists in the database.
+    $deleted_answer = QuestionAnswer::load($answer_id);
+    $this->assertNull($deleted_answer);
+  }
+
+}
diff --git a/tests/src/Kernel/QuestionKernelTest.php b/tests/src/Kernel/QuestionKernelTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..4df74e35f5349a1c31e4243996b96d3fd41a131b
--- /dev/null
+++ b/tests/src/Kernel/QuestionKernelTest.php
@@ -0,0 +1,212 @@
+<?php
+
+namespace Drupal\Tests\quiz_maker\Kernel;
+
+use Drupal\quiz_maker\Entity\Question;
+use Drupal\Tests\quiz_maker\Traits\QuestionCreateTrait;
+
+/**
+ * Tests creation of Quiz Question.
+ *
+ * @group quiz_maker
+ */
+class QuestionKernelTest extends QuizKernelTestBase {
+
+  use QuestionCreateTrait;
+
+  /**
+   * Tests the creation boolean Question.
+   */
+  public function testBooleanQuestionCreate() {
+    $question = $this->createBooleanQuestion();
+
+    $this->assertEquals('Boolean Question', $question->label());
+    $this->assertEquals('boolean_question', $question->bundle());
+    $this->assertEquals('Boolean Question?', $question->get('question')->value);
+    $this->assertEquals(100, $question->get('max_score')->value);
+  }
+
+  /**
+   * Tests the creation boolean Question.
+   */
+  public function testBooleanQuestionUpdate() {
+    $question = $this->createBooleanQuestion();
+
+    $question->set('question', 'Updated Boolean Question?');
+    $question->set('max_score', 200);
+
+    $this->assertEquals('Updated Boolean Question?', $question->get('question')->value);
+    $this->assertEquals(200, $question->get('max_score')->value);
+  }
+
+  /**
+   * Tests the creation boolean Question.
+   */
+  public function testBooleanQuestionDelete() {
+    $question = $this->createBooleanQuestion();
+
+    $question_id = $question->id();
+    $question->delete();
+
+    // Assert that the quiz no longer exists in the database.
+    $deleted_quiz = Question::load($question_id);
+    $this->assertNull($deleted_quiz);
+  }
+
+  /**
+   * Tests the creation direct Question.
+   */
+  public function testDirectQuestionCreate() {
+    $question = $this->createDirectQuestion();
+
+    $this->assertEquals('Direct Question', $question->label());
+    $this->assertEquals('direct_question', $question->bundle());
+    $this->assertEquals('Direct Question?', $question->get('question')->value);
+    $this->assertEquals(100, $question->get('max_score')->value);
+  }
+
+  /**
+   * Tests the creation direct Question.
+   */
+  public function testDirectQuestionUpdate() {
+    $question = $this->createDirectQuestion();
+
+    $question->set('question', 'Updated Direct Question?');
+    $question->set('max_score', 200);
+
+    $this->assertEquals('Updated Direct Question?', $question->get('question')->value);
+    $this->assertEquals(200, $question->get('max_score')->value);
+  }
+
+  /**
+   * Tests the creation direct Question.
+   */
+  public function testDirectQuestionDelete() {
+    $question = $this->createDirectQuestion();
+
+    $question_id = $question->id();
+    $question->delete();
+
+    // Assert that the question no longer exists in the database.
+    $deleted_question = Question::load($question_id);
+    $this->assertNull($deleted_question);
+  }
+
+  /**
+   * Tests the creation Matching Question.
+   */
+  public function testMatchingQuestionCreate() {
+    $question = $this->createMatchingQuestion();
+
+    $this->assertEquals('Matching Question', $question->label());
+    $this->assertEquals('matching_question', $question->bundle());
+    $this->assertEquals('Matching Question?', $question->get('question')->value);
+    $this->assertEquals(100, $question->get('max_score')->value);
+  }
+
+  /**
+   * Tests the creation Matching Question.
+   */
+  public function testMatchingQuestionUpdate() {
+    $question = $this->createMatchingQuestion();
+
+    $question->set('question', 'Updated Matching Question?');
+    $question->set('max_score', 200);
+
+    $this->assertEquals('Updated Matching Question?', $question->get('question')->value);
+    $this->assertEquals(200, $question->get('max_score')->value);
+  }
+
+  /**
+   * Tests the creation Matching Question.
+   */
+  public function testMatchingQuestionDelete() {
+    $question = $this->createMatchingQuestion();
+
+    $question_id = $question->id();
+    $question->delete();
+
+    // Assert that the question no longer exists in the database.
+    $deleted_question = Question::load($question_id);
+    $this->assertNull($deleted_question);
+  }
+
+  /**
+   * Tests the creation Multiple Choice Question.
+   */
+  public function testMultipleChoiceQuestionCreate() {
+    $question = $this->createMultipleChoiceQuestion();
+
+    $this->assertEquals('Multiple Choice Question', $question->label());
+    $this->assertEquals('multiple_choice_question', $question->bundle());
+    $this->assertEquals('Multiple Choice Question?', $question->get('question')->value);
+    $this->assertEquals(100, $question->get('max_score')->value);
+  }
+
+  /**
+   * Tests the creation Multiple Choice Question.
+   */
+  public function testMultipleChoiceQuestionUpdate() {
+    $question = $this->createMultipleChoiceQuestion();
+
+    $question->set('question', 'Updated Multiple Choice Question?');
+    $question->set('max_score', 200);
+
+    $this->assertEquals('Updated Multiple Choice Question?', $question->get('question')->value);
+    $this->assertEquals(200, $question->get('max_score')->value);
+  }
+
+  /**
+   * Tests the creation MultipleChoice Question.
+   */
+  public function testMultipleChoiceQuestionDelete() {
+    $question = $this->createMultipleChoiceQuestion();
+
+    $question_id = $question->id();
+    $question->delete();
+
+    // Assert that the question no longer exists in the database.
+    $deleted_question = Question::load($question_id);
+    $this->assertNull($deleted_question);
+  }
+
+  /**
+   * Tests the creation Single Choice Question.
+   */
+  public function testSingleChoiceQuestionCreate() {
+    $question = $this->createSingleChoiceQuestion();
+
+    $this->assertEquals('Single Choice Question', $question->label());
+    $this->assertEquals('single_choice_question', $question->bundle());
+    $this->assertEquals('Single Choice Question?', $question->get('question')->value);
+    $this->assertEquals(100, $question->get('max_score')->value);
+  }
+
+  /**
+   * Tests the creation Single Choice Question.
+   */
+  public function testSingleChoiceQuestionUpdate() {
+    $question = $this->createSingleChoiceQuestion();
+
+    $question->set('question', 'Updated Single Choice Question?');
+    $question->set('max_score', 200);
+
+    $this->assertEquals('Updated Single Choice Question?', $question->get('question')->value);
+    $this->assertEquals(200, $question->get('max_score')->value);
+  }
+
+  /**
+   * Tests the creation Single Choice Question.
+   */
+  public function testSingleChoiceQuestionDelete() {
+    $question = $this->createSingleChoiceQuestion();
+
+    $question_id = $question->id();
+    $question->delete();
+
+    // Assert that the question no longer exists in the database.
+    $deleted_question = Question::load($question_id);
+    $this->assertNull($deleted_question);
+  }
+
+}
diff --git a/tests/src/Kernel/QuestionResponseKernelTest.php b/tests/src/Kernel/QuestionResponseKernelTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..744656bac915c4dd2f97280b599a33bb329068fd
--- /dev/null
+++ b/tests/src/Kernel/QuestionResponseKernelTest.php
@@ -0,0 +1,212 @@
+<?php
+
+namespace Drupal\Tests\quiz_maker\Kernel;
+
+use Drupal\quiz_maker\Entity\QuestionResponse;
+use Drupal\Tests\quiz_maker\Traits\QuestionResponseCreateTrait;
+
+/**
+ * Tests creation of Quiz Question Response.
+ *
+ * @group quiz_maker
+ */
+class QuestionResponseKernelTest extends QuizKernelTestBase {
+
+  use QuestionResponseCreateTrait;
+
+  /**
+   * Tests the creation boolean Answer.
+   */
+  public function testBooleanResponseCreate() {
+    $answer = $this->createBooleanResponse();
+
+    $this->assertEquals('Boolean response', $answer->label());
+    $this->assertEquals('boolean_response', $answer->bundle());
+    $this->assertEquals('Boolean response', $answer->get('label')->value);
+    $this->assertEquals(FALSE, $answer->get('is_correct')->value);
+  }
+
+  /**
+   * Tests the updating boolean response.
+   */
+  public function testBooleanResponseUpdate() {
+    $answer = $this->createBooleanResponse();
+
+    $answer->set('label', 'Updated Boolean Answer');
+    $answer->set('is_correct', TRUE);
+
+    $this->assertEquals('Updated Boolean Answer', $answer->get('label')->value);
+    $this->assertEquals(TRUE, $answer->get('is_correct')->value);
+  }
+
+  /**
+   * Tests the deleting boolean response.
+   */
+  public function testBooleanResponseDelete() {
+    $response = $this->createBooleanResponse();
+
+    $response_id = $response->id();
+    $response->delete();
+
+    // Assert that the quiz no longer exists in the database.
+    $deleted_answer = QuestionResponse::load($response_id);
+    $this->assertNull($deleted_answer);
+  }
+
+  /**
+   * Tests the creation of Direct response.
+   */
+  public function testDirectResponseCreate() {
+    $response = $this->createDirectResponse();
+
+    $this->assertEquals('Direct response', $response->label());
+    $this->assertEquals('direct_response', $response->bundle());
+    $this->assertEquals('Direct response', $response->get('label')->value);
+    $this->assertEquals(FALSE, $response->get('is_correct')->value);
+  }
+
+  /**
+   * Tests the updating of Direct response.
+   */
+  public function testDirectResponseUpdate() {
+    $response = $this->createDirectResponse();
+
+    $response->set('label', 'Updated Direct Answer');
+    $response->set('is_correct', TRUE);
+
+    $this->assertEquals('Updated Direct Answer', $response->get('label')->value);
+    $this->assertEquals(TRUE, $response->get('is_correct')->value);
+  }
+
+  /**
+   * Tests the deleting of Direct response.
+   */
+  public function testDirectResponseDelete() {
+    $response = $this->createDirectResponse();
+
+    $response_id = $response->id();
+    $response->delete();
+
+    // Assert that the response no longer exists in the database.
+    $deleted_response = QuestionResponse::load($response_id);
+    $this->assertNull($deleted_response);
+  }
+
+  /**
+   * Tests the creation of Matching response.
+   */
+  public function testMatchingResponseCreate() {
+    $response = $this->createMatchingResponse();
+
+    $this->assertEquals('Matching response', $response->label());
+    $this->assertEquals('matching_choice_response', $response->bundle());
+    $this->assertEquals('Matching response', $response->get('label')->value);
+    $this->assertEquals(FALSE, $response->get('is_correct')->value);
+  }
+
+  /**
+   * Tests the updating of Matching response.
+   */
+  public function testMatchingResponseUpdate() {
+    $response = $this->createMatchingResponse();
+
+    $response->set('label', 'Updated Matching Answer');
+    $response->set('is_correct', TRUE);
+
+    $this->assertEquals('Updated Matching Answer', $response->get('label')->value);
+    $this->assertEquals(TRUE, $response->get('is_correct')->value);
+  }
+
+  /**
+   * Tests the deleting of Matching response.
+   */
+  public function testMatchingResponseDelete() {
+    $response = $this->createMatchingResponse();
+
+    $response_id = $response->id();
+    $response->delete();
+
+    // Assert that the response no longer exists in the database.
+    $deleted_response = QuestionResponse::load($response_id);
+    $this->assertNull($deleted_response);
+  }
+
+  /**
+   * Tests the creation of Multiple choice response.
+   */
+  public function testMultipleChoiceResponseCreate() {
+    $response = $this->createMultipleChoiceResponse();
+
+    $this->assertEquals('Multiple choice response', $response->label());
+    $this->assertEquals('multiple_choice_response', $response->bundle());
+    $this->assertEquals('Multiple choice response', $response->get('label')->value);
+    $this->assertEquals(FALSE, $response->get('is_correct')->value);
+  }
+
+  /**
+   * Tests the updating of Multiple choice response.
+   */
+  public function testMultipleChoiceResponseUpdate() {
+    $response = $this->createMultipleChoiceResponse();
+
+    $response->set('label', 'Updated Multiple Choice Answer');
+    $response->set('is_correct', TRUE);
+
+    $this->assertEquals('Updated Multiple Choice Answer', $response->get('label')->value);
+    $this->assertEquals(TRUE, $response->get('is_correct')->value);
+  }
+
+  /**
+   * Tests the deleting of Multiple choice response.
+   */
+  public function testMultipleChoiceResponseDelete() {
+    $response = $this->createMultipleChoiceResponse();
+
+    $response_id = $response->id();
+    $response->delete();
+
+    // Assert that the response no longer exists in the database.
+    $deleted_response = QuestionResponse::load($response_id);
+    $this->assertNull($deleted_response);
+  }
+
+  /**
+   * Tests the creation of Single choice response.
+   */
+  public function testSingleChoiceResponseCreate() {
+    $response = $this->createSingleChoiceResponse();
+
+    $this->assertEquals('Single choice response', $response->label());
+    $this->assertEquals('single_choice_response', $response->bundle());
+    $this->assertEquals('Single choice response', $response->get('label')->value);
+    $this->assertEquals(FALSE, $response->get('is_correct')->value);
+  }
+
+  /**
+   * Tests the updating of Single choice response.
+   */
+  public function testSingleChoiceResponseUpdate() {
+    $response = $this->createSingleChoiceResponse();
+
+    $response->set('label', 'Updated Single Choice Answer');
+    $response->set('is_correct', TRUE);
+
+    $this->assertEquals('Updated Single Choice Answer', $response->get('label')->value);
+    $this->assertEquals(TRUE, $response->get('is_correct')->value);
+  }
+
+  /**
+   * Tests the deleting of Single choice response.
+   */
+  public function testSingleChoiceResponseDelete() {
+    $response = $this->createSingleChoiceResponse();
+
+    $response_id = $response->id();
+    $response->delete();
+
+    // Assert that the response no longer exists in the database.
+    $deleted_response = QuestionResponse::load($response_id);
+    $this->assertNull($deleted_response);
+  }
+
+}
diff --git a/tests/src/Kernel/QuizKernelTest.php b/tests/src/Kernel/QuizKernelTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..d7165e3afc84e0d22de0c09a8d6da2eb5bfd3a0e
--- /dev/null
+++ b/tests/src/Kernel/QuizKernelTest.php
@@ -0,0 +1,88 @@
+<?php
+
+namespace Drupal\Tests\quiz_maker\Kernel;
+
+use Drupal\quiz_maker\Entity\Quiz;
+
+/**
+ * Tests creation of Quiz.
+ *
+ * @group quiz_maker
+ */
+class QuizKernelTest extends QuizKernelTestBase {
+
+  /**
+   * Tests the creation Quiz.
+   */
+  public function testStandardQuizCreation() {
+    $quiz = Quiz::create([
+      'bundle' => 'standard',
+      'label' => 'Empty quiz',
+      'description' => 'Empty quiz',
+      'result_type' => 'standard',
+      'manual_assessment' => FALSE,
+      'allow_backwards_navigation' => FALSE,
+      'allow_jumping' => FALSE,
+      'allow_skipping' => FALSE,
+      'allow_changing_answers' => FALSE,
+      'attempts' => 5,
+    ]);
+
+    $quiz->save();
+
+    $this->assertEquals('Empty quiz', $quiz->label());
+    $this->assertEquals(FALSE, $quiz->requireManualAssessment());
+    $this->assertEquals(FALSE, $quiz->allowBackwardNavigation());
+    $this->assertEquals(FALSE, $quiz->allowJumping());
+    $this->assertEquals(FALSE, $quiz->allowSkipping());
+    $this->assertEquals(FALSE, $quiz->allowChangeAnswer());
+    $this->assertEquals(5, $quiz->getAllowedAttempts());
+  }
+
+  /**
+   * Tests the updating Quiz.
+   */
+  public function testStandardQuizUpdate() {
+    $quiz = Quiz::create([
+      'bundle' => 'standard',
+      'label' => 'Empty quiz',
+      'description' => 'Empty quiz',
+      'result_type' => 'standard',
+      'attempts' => 5,
+    ]);
+
+    $quiz->save();
+
+    $quiz->set('label', 'Updated quiz');
+    $quiz->set('attempts', 6);
+    $quiz->save();
+
+    $updated_quiz = Quiz::load($quiz->id());
+    $this->assertEquals('Updated quiz', $updated_quiz->label());
+    $this->assertEquals(6, $updated_quiz->getAllowedAttempts());
+  }
+
+  /**
+   * Tests the deleting Quiz.
+   */
+  public function testStandardQuizDelete() {
+    $quiz = Quiz::create([
+      'bundle' => 'standard',
+      'label' => 'Empty quiz',
+      'description' => 'Empty quiz',
+      'result_type' => 'standard',
+      'attempts' => 5,
+    ]);
+
+    $quiz->save();
+
+    // Get the quiz ID and delete it.
+    $quiz_id = $quiz->id();
+    $quiz->delete();
+
+    // Assert that the quiz no longer exists in the database.
+    $deleted_quiz = Quiz::load($quiz_id);
+    $this->assertNull($deleted_quiz);
+  }
+
+}
diff --git a/tests/src/Kernel/QuizKernelTestBase.php b/tests/src/Kernel/QuizKernelTestBase.php
new file mode 100644
index 0000000000000000000000000000000000000000..3db0e3e0da353bf1700e19bbb774062db1dd4b95
--- /dev/null
+++ b/tests/src/Kernel/QuizKernelTestBase.php
@@ -0,0 +1,59 @@
+<?php
+
+namespace Drupal\Tests\quiz_maker\Kernel;
+
+use Drupal\KernelTests\KernelTestBase;
+use Drupal\user\Entity\User;
+
+/**
+ * Base class for Quiz kernel tests.
+ */
+abstract class QuizKernelTestBase extends KernelTestBase {
+
+  /**
+   * Modules to install.
+   *
+   * @var array
+   */
+  public static $modules = [
+    'quiz_maker',
+    'user',
+    'field',
+    'text',
+    'taxonomy',
+    'system',
+    'datetime_range',
+    'editor',
+    'entity_reference_revisions',
+    'inline_entity_form',
+    'field_group',
+    'views_bulk_operations',
+    'entity_browser',
+    'entity',
+    'state_machine',
+    'paragraphs',
+    'addtoany',
+  ];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp(): void {
+    parent::setUp();
+
+    $this->installEntitySchema('user');
+    $this->installEntitySchema('quiz');
+    $this->installEntitySchema('question');
+    $this->installEntitySchema('question_answer');
+    $this->installEntitySchema('question_response');
+    $this->installEntitySchema('quiz_result');
+
+    $this->user = User::create([
+      'name' => 'username',
+      'status' => 1,
+    ]);
+    $this->user->save();
+    $this->container->get('current_user')->setAccount($this->user);
+  }
+
+}
diff --git a/tests/src/Kernel/QuizResultKernelTest.php b/tests/src/Kernel/QuizResultKernelTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..4bfabcb8c92d99c0ba2bfa4cadebee3435d1cdfa
--- /dev/null
+++ b/tests/src/Kernel/QuizResultKernelTest.php
@@ -0,0 +1,76 @@
+<?php
+
+namespace Drupal\Tests\quiz_maker\Kernel;
+
+use Drupal\quiz_maker\Entity\QuizResult;
+
+/**
+ * Tests creation of Quiz Result.
+ *
+ * @group quiz_maker
+ */
+class QuizResultKernelTest extends QuizKernelTestBase {
+
+  /**
+   * Tests the creation Quiz Result.
+   */
+  public function testStandardQuizResultCreate() {
+    $quiz_result = QuizResult::create([
+      'bundle' => 'standard',
+      'label' => 'Quiz result test',
+      'score' => 1.0,
+      'state' => 'completed',
+      'attempt' => 1,
+    ]);
+
+    $quiz_result->save();
+
+    $this->assertEquals('Quiz result test', $quiz_result->label());
+    $this->assertEquals(1.0, $quiz_result->getScore());
+  }
+
+  /**
+   * Tests the updating Quiz.
+   */
+  public function testStandardQuizUpdate() {
+    $quiz_result = QuizResult::create([
+      'bundle' => 'standard',
+      'label' => 'Quiz result test',
+      'score' => 1.0,
+      'state' => 'completed',
+      'attempt' => 1,
+    ]);
+
+    $quiz_result->save();
+
+    $quiz_result->set('label', 'Updated Quiz result test');
+    $quiz_result->save();
+
+    $updated_quiz_result = QuizResult::load($quiz_result->id());
+    $this->assertEquals('Updated Quiz result test', $updated_quiz_result->label());
+  }
+
+  /**
+   * Tests the deleting Quiz result.
+   */
+  public function testStandardQuizResultDelete() {
+    $quiz_result = QuizResult::create([
+      'bundle' => 'standard',
+      'label' => 'Quiz result test',
+      'score' => 1.0,
+      'state' => 'completed',
+      'attempt' => 1,
+    ]);
+
+    $quiz_result->save();
+
+    // Get the quiz ID and delete it.
+    $quiz_result_id = $quiz_result->id();
+    $quiz_result->delete();
+
+    // Assert that the quiz result no longer exists in the database.
+    $deleted_quiz = QuizResult::load($quiz_result_id);
+    $this->assertNull($deleted_quiz);
+  }
+
+}
diff --git a/tests/src/Traits/QuestionAnswerCreateTrait.php b/tests/src/Traits/QuestionAnswerCreateTrait.php
new file mode 100644
index 0000000000000000000000000000000000000000..744d5f18aa232f4c4875402828a298243fd70a7c
--- /dev/null
+++ b/tests/src/Traits/QuestionAnswerCreateTrait.php
@@ -0,0 +1,92 @@
+<?php
+
+namespace Drupal\Tests\quiz_maker\Traits;
+
+use Drupal\quiz_maker\Entity\QuestionAnswer;
+
+/**
+ * Provide common helper methods for Quiz Question Answers.
+ */
+trait QuestionAnswerCreateTrait {
+
+  /**
+   * Create boolean answer.
+   */
+  public function createBooleanAnswer() {
+    $answer = QuestionAnswer::create([
+      'bundle' => 'boolean_answer',
+      'label' => 'Boolean answer',
+      'answer' => 'Boolean answer',
+      'is_correct' => FALSE,
+    ]);
+
+    $answer->save();
+
+    return $answer;
+  }
+
+  /**
+   * Create direct answer.
+   */
+  public function createDirectAnswer() {
+    $answer = QuestionAnswer::create([
+      'bundle' => 'direct_answer',
+      'label' => 'Direct answer',
+      'answer' => 'Direct answer',
+      'is_correct' => FALSE,
+    ]);
+
+    $answer->save();
+
+    return $answer;
+  }
+
+  /**
+   * Create Matching answer.
+   */
+  public function createMatchingAnswer() {
+    $answer = QuestionAnswer::create([
+      'bundle' => 'matching_answer',
+      'label' => 'Matching answer',
+      'answer' => 'Matching answer',
+      'is_correct' => FALSE,
+    ]);
+
+    $answer->save();
+
+    return $answer;
+  }
+
+  /**
+   * Create Multiple Choice answer.
+   */
+  public function createMultipleChoiceAnswer() {
+    $answer = QuestionAnswer::create([
+      'bundle' => 'multiple_choice_answer',
+      'label' => 'Multiple Choice answer',
+      'answer' => 'Multiple Choice answer',
+      'is_correct' => FALSE,
+    ]);
+
+    $answer->save();
+
+    return $answer;
+  }
+
+  /**
+   * Create Single Choice answer.
+   */
+  public function createSingleChoiceAnswer() {
+    $answer = QuestionAnswer::create([
+      'bundle' => 'single_choice_answer',
+      'label' => 'Single Choice answer',
+      'answer' => 'Single Choice answer',
+      'is_correct' => FALSE,
+    ]);
+
+    $answer->save();
+
+    return $answer;
+  }
+
+}
diff --git a/tests/src/Traits/QuestionCreateTrait.php b/tests/src/Traits/QuestionCreateTrait.php
new file mode 100644
index 0000000000000000000000000000000000000000..168bbda82d0f178ec838d8235f71195494e908ac
--- /dev/null
+++ b/tests/src/Traits/QuestionCreateTrait.php
@@ -0,0 +1,102 @@
+<?php
+
+namespace Drupal\Tests\quiz_maker\Traits;
+
+use Drupal\quiz_maker\Entity\Question;
+
+/**
+ * Provide common helper methods for Quiz Questions.
+ */
+trait QuestionCreateTrait {
+
+  /**
+   * Create boolean question.
+   */
+  public function createBooleanQuestion() {
+    $question = Question::create([
+      'bundle' => 'boolean_question',
+      'label' => 'Boolean Question',
+      'description' => 'Boolean Question',
+      'question' => 'Boolean Question?',
+      'response_type' => 'boolean_response',
+      'max_score' => 100,
+    ]);
+
+    $question->save();
+
+    return $question;
+  }
+
+  /**
+   * Create direct question.
+   */
+  public function createDirectQuestion() {
+    $question = Question::create([
+      'bundle' => 'direct_question',
+      'label' => 'Direct Question',
+      'description' => 'Direct Question',
+      'question' => 'Direct Question?',
+      'response_type' => 'direct_response',
+      'max_score' => 100,
+    ]);
+
+    $question->save();
+
+    return $question;
+  }
+
+  /**
+   * Create matching question.
+   */
+  public function createMatchingQuestion() {
+    $question = Question::create([
+      'bundle' => 'matching_question',
+      'label' => 'Matching Question',
+      'description' => 'Matching Question',
+      'question' => 'Matching Question?',
+      'response_type' => 'matching_response',
+      'max_score' => 100,
+    ]);
+
+    $question->save();
+
+    return $question;
+  }
+
+  /**
+   * Create multiple choice question.
+   */
+  public function createMultipleChoiceQuestion() {
+    $question = Question::create([
+      'bundle' => 'multiple_choice_question',
+      'label' => 'Multiple Choice Question',
+      'description' => 'Multiple Choice Question',
+      'question' => 'Multiple Choice Question?',
+      'response_type' => 'multiple_choice_response',
+      'max_score' => 100,
+    ]);
+
+    $question->save();
+
+    return $question;
+  }
+
+  /**
+   * Create single choice question.
+   */
+  public function createSingleChoiceQuestion() {
+    $question = Question::create([
+      'bundle' => 'single_choice_question',
+      'label' => 'Single Choice Question',
+      'description' => 'Single Choice Question',
+      'question' => 'Single Choice Question?',
+      'response_type' => 'single_choice_response',
+      'max_score' => 100,
+    ]);
+
+    $question->save();
+
+    return $question;
+  }
+
+}
diff --git a/tests/src/Traits/QuestionResponseCreateTrait.php b/tests/src/Traits/QuestionResponseCreateTrait.php
new file mode 100644
index 0000000000000000000000000000000000000000..573e0289215c9752a7a1f3359948216a70fd82a7
--- /dev/null
+++ b/tests/src/Traits/QuestionResponseCreateTrait.php
@@ -0,0 +1,92 @@
+<?php
+
+namespace Drupal\Tests\quiz_maker\Traits;
+
+use Drupal\quiz_maker\Entity\QuestionResponse;
+
+/**
+ * Provide common helper methods for Quiz Question Answers.
+ */
+trait QuestionResponseCreateTrait {
+
+  /**
+   * Create boolean response.
+   */
+  public function createBooleanResponse() {
+    $answer = QuestionResponse::create([
+      'bundle' => 'boolean_response',
+      'label' => 'Boolean response',
+      'is_correct' => FALSE,
+      'score' => 0.5,
+    ]);
+
+    $answer->save();
+
+    return $answer;
+  }
+
+  /**
+   * Create direct response.
+   */
+  public function createDirectResponse() {
+    $answer = QuestionResponse::create([
+      'bundle' => 'direct_response',
+      'label' => 'Direct response',
+      'is_correct' => FALSE,
+      'score' => 0.5,
+    ]);
+
+    $answer->save();
+
+    return $answer;
+  }
+
+  /**
+   * Create matching response.
+   */
+  public function createMatchingResponse() {
+    $answer = QuestionResponse::create([
+      'bundle' => 'matching_choice_response',
+      'label' => 'Matching response',
+      'is_correct' => FALSE,
+      'score' => 0.5,
+    ]);
+
+    $answer->save();
+
+    return $answer;
+  }
+
+  /**
+   * Create multiple choice response.
+   */
+  public function createMultipleChoiceResponse() {
+    $answer = QuestionResponse::create([
+      'bundle' => 'multiple_choice_response',
+      'label' => 'Multiple choice response',
+      'is_correct' => FALSE,
+      'score' => 0.5,
+    ]);
+
+    $answer->save();
+
+    return $answer;
+  }
+
+  /**
+   * Create single choice response.
+   */
+  public function createSingleChoiceResponse() {
+    $answer = QuestionResponse::create([
+      'bundle' => 'single_choice_response',
+      'label' => 'Single choice response',
+      'is_correct' => FALSE,
+      'score' => 0.5,
+    ]);
+
+    $answer->save();
+
+    return $answer;
+  }
+
+}
diff --git a/tests/src/Traits/QuizCreateTrait.php b/tests/src/Traits/QuizCreateTrait.php
new file mode 100644
index 0000000000000000000000000000000000000000..8dc3ad6783846039a998028fa46c7c2a526f5af3
--- /dev/null
+++ b/tests/src/Traits/QuizCreateTrait.php
@@ -0,0 +1,183 @@
+<?php
+
+namespace Drupal\Tests\quiz_maker\Traits;
+
+use Drupal\quiz_maker\Entity\Question;
+use Drupal\quiz_maker\Entity\QuestionAnswer;
+use Drupal\quiz_maker\Entity\Quiz;
+
+/**
+ * Provide common helper methods for Quiz creation.
+ */
+trait QuizCreateTrait {
+
+  /**
+   * Get multiple choice question with answer.
+   */
+  public function getMultipleChoiceQuestionWithAnswers(): Question {
+    $answers = [];
+
+    for ($i = 1; $i <= 5; $i++) {
+      $answer = QuestionAnswer::create([
+        'bundle' => 'multiple_choice_answer',
+        'label' => "Answer $i",
+        'answer' => "Answer $i",
+        'is_correct' => $i % 2 === 0,
+      ]);
+      $answer->save();
+      $answers[] = $answer;
+    }
+
+    $question = Question::create([
+      'bundle' => 'multiple_choice_question',
+      'label' => 'Multiple Choice Question',
+      'description' => 'Multiple Choice Question',
+      'question' => 'Multiple Choice Question?',
+      'response_type' => 'multiple_choice_response',
+      'max_score' => 100,
+      'answers' => $answers,
+    ]);
+
+    $question->save();
+
+    return $question;
+  }
+
+  /**
+   * Get single choice question with answer.
+   */
+  public function getSingleChoiceQuestionWithAnswers(): Question {
+    $answers = [];
+
+    for ($i = 1; $i <= 5; $i++) {
+      $answer = QuestionAnswer::create([
+        'bundle' => 'single_choice_answer',
+        'label' => "Answer $i",
+        'answer' => "Answer $i",
+        'is_correct' => $i % 2 === 0,
+      ]);
+      $answer->save();
+      $answers[] = $answer;
+    }
+
+    $question = Question::create([
+      'bundle' => 'single_choice_question',
+      'label' => 'Single Choice Question',
+      'description' => 'Single Choice Question',
+      'question' => 'Single Choice Question?',
+      'response_type' => 'single_choice_response',
+      'max_score' => 100,
+      'answers' => $answers,
+    ]);
+
+    $question->save();
+
+    return $question;
+  }
+
+  /**
+   * Get matching question with answer.
+   */
+  public function getMatchingQuestionWithAnswers(): Question {
+    $answers = [];
+
+    for ($i = 1; $i <= 5; $i++) {
+      $answer = QuestionAnswer::create([
+        'bundle' => 'matching_answer',
+        'label' => "Answer $i",
+        'field_matching_question' => "Question $i",
+        'field_matching_answer' => "Answer $i",
+      ]);
+      $answer->save();
+      $answers[] = $answer;
+    }
+
+    $question = Question::create([
+      'bundle' => 'matching_question',
+      'label' => 'Matching Question',
+      'description' => 'Matching Question',
+      'question' => 'Matching Question?',
+      'response_type' => 'matching_response',
+      'max_score' => 100,
+      'answers' => $answers,
+    ]);
+
+    $question->save();
+
+    return $question;
+  }
+
+  /**
+   * Get direct question with answer.
+   */
+  public function getDirectQuestionWithAnswers(): Question {
+    $answers = [];
+
+    for ($i = 1; $i <= 5; $i++) {
+      $answer = QuestionAnswer::create([
+        'bundle' => 'direct_answer',
+        'label' => "Answer $i",
+        'answer' => "Answer $i",
+      ]);
+      $answer->save();
+      $answers[] = $answer;
+    }
+
+    $question = Question::create([
+      'bundle' => 'direct_question',
+      'label' => 'Direct Question',
+      'description' => 'Direct Question',
+      'question' => 'Direct Question?',
+      'response_type' => 'direct_response',
+      'max_score' => 100,
+      'answers' => $answers,
+    ]);
+
+    $question->save();
+
+    return $question;
+  }
+
+  /**
+   * Get boolean question with answer.
+   */
+  public function getBooleanQuestionWithAnswers(): Question {
+    $question = Question::create([
+      'bundle' => 'boolean_question',
+      'label' => 'Boolean Question',
+      'description' => 'Boolean Question',
+      'question' => 'Boolean Question?',
+      'response_type' => 'boolean_response',
+      'max_score' => 100,
+    ]);
+
+    $question->save();
+
+    return $question;
+  }
+
+  /**
+   * Get quiz.
+   */
+  public function getQuiz(): Quiz {
+    $quiz = Quiz::create([
+      'bundle' => 'standard',
+      'label' => 'Empty quiz',
+      'description' => 'Empty quiz',
+      'result_type' => 'standard',
+      'attempts' => 5,
+    ]);
+
+    $quiz->set('questions', [
+      $this->getDirectQuestionWithAnswers(),
+      $this->getBooleanQuestionWithAnswers(),
+      $this->getMatchingQuestionWithAnswers(),
+      $this->getMultipleChoiceQuestionWithAnswers(),
+      $this->getSingleChoiceQuestionWithAnswers(),
+    ]);
+
+    $quiz->save();
+    return $quiz;
+  }
+
+}