diff --git a/unit-tests/card.cpp b/unit-tests/card.cpp
index 72e2cd66783896b100caf5762cfa6c185eb5cd35..658608ac372e1ff3227a88be2b6dcfc838301fca 100644
--- a/unit-tests/card.cpp
+++ b/unit-tests/card.cpp
@@ -1,5 +1,5 @@
 //
-// Created by Manuel Nowack on 10.04.21.
+// Created by Aidan Meara on 23.11.24.
 //
 
 #include "gtest/gtest.h"
diff --git a/unit-tests/deck.cpp b/unit-tests/deck.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..71f95ea30b5febfbe68fcf31a6d07e1e7293078a
--- /dev/null
+++ b/unit-tests/deck.cpp
@@ -0,0 +1,271 @@
+//
+// Created by Aidan Meara on 23.11.24.
+//
+
+#include "gtest/gtest.h"
+#include "../src/common/game_state/cards/deck.h"
+
+// new deck must hold 60 cards
+TEST(DeckTest, Creation) {
+  deck mydeck;
+  ASSERT_EQ(mydeck._all_cards.size(), 60);
+
+}
+
+
+/* A test fixture allows us to reuse the same configuration of objects for all
+ * tests in a test suite. The name of the fixture must match the test suite.
+ *
+ * For each test defined with TEST_F(), googletest will create a fresh test
+ * fixture at runtime, immediately initialize it via SetUp(), run the test,
+ * clean up by calling TearDown(), and then delete the test fixture.
+ * Note that different tests in the same test suite have different test fixture
+ * objects, and googletest always deletes a test fixture before it creates the
+ * next one. googletest does not reuse the same test fixture for multiple
+ * tests. Any changes one test makes to the fixture do not affect other tests.
+ */
+
+class HandTest : public ::testing::Test {
+
+protected:
+    virtual void SetUp() {
+        cards.resize(8);
+        for (int i = 1; i < 8; ++i) {
+            for (int j = 0; j < 8; ++j) {
+                cards[i].push_back(new card(i));
+            }
+        }
+    }
+
+    /* Any object and subroutine declared here can be accessed in the tests */
+
+    // cards[i][j] holds a pointer to the j-th copy of a card of value i
+    std::vector<std::vector<card*>> cards;
+    hand player_hand;
+    std::string err;
+};
+
+// Adding one card to an empty hand must succeed
+TEST_F(HandTest, AddOneCard) {
+    EXPECT_TRUE(player_hand.add_card(cards[1][0], err));
+    std::vector<card*> expected_hand = {cards[1][0]};
+    EXPECT_EQ(expected_hand, player_hand.get_cards());
+}
+
+// The initial state must be an empty hand
+TEST_F(HandTest, AddNoCards) {
+    std::vector<card*> expected_hand = {};
+    EXPECT_EQ(expected_hand, player_hand.get_cards());
+}
+
+// Adding several cards with different values to an empty hand must succeed
+TEST_F(HandTest, AddManyCards) {
+    EXPECT_TRUE(player_hand.add_card(cards[1][0], err));
+    EXPECT_TRUE(player_hand.add_card(cards[3][0], err));
+    EXPECT_TRUE(player_hand.add_card(cards[7][0], err));
+    std::vector<card*> expected_hand = {cards[1][0], cards[3][0], cards[7][0]};
+    EXPECT_EQ(expected_hand, player_hand.get_cards());
+}
+
+// Adding several cards with duplicate values to an empty hand must succeed
+TEST_F(HandTest, AddManyCardsWithDuplicates) {
+    EXPECT_TRUE(player_hand.add_card(cards[1][0], err));
+    EXPECT_TRUE(player_hand.add_card(cards[1][1], err));
+    EXPECT_TRUE(player_hand.add_card(cards[1][2], err));
+    EXPECT_TRUE(player_hand.add_card(cards[3][0], err));
+    EXPECT_TRUE(player_hand.add_card(cards[3][1], err));
+    EXPECT_TRUE(player_hand.add_card(cards[7][0], err));
+    std::vector<card*> expected_hand = {cards[1][0], cards[1][1], cards[1][2],
+                                        cards[3][0], cards[3][1], cards[7][0]};
+    EXPECT_EQ(expected_hand, player_hand.get_cards());
+}
+
+// Removing one card from a hand of three cards must succeed
+TEST_F(HandTest, RemoveOneCard) {
+    player_hand.add_card(cards[1][0], err);
+    player_hand.add_card(cards[3][0], err);
+    player_hand.add_card(cards[7][0], err);
+
+    card* to_remove = cards[1][0];
+    card* removed_card = nullptr;
+    EXPECT_TRUE(player_hand.remove_card(to_remove->get_id(), removed_card, err));
+    std::vector<card*> expected_hand = {cards[3][0], cards[7][0]};
+    EXPECT_EQ(to_remove, removed_card);
+    EXPECT_EQ(expected_hand, player_hand.get_cards());
+}
+
+// Removing a card from an empty hand must fail
+// Removing a nonexistent card from a hand of three cards must fail
+TEST_F(HandTest, RemoveNonexistentCards) {
+    card* to_remove = cards[1][0];
+    card* removed_card = cards[1][0];
+    EXPECT_FALSE(player_hand.remove_card(to_remove->get_id(), removed_card, err));
+    std::vector<card*> expected_hand = {};
+    EXPECT_EQ(nullptr, removed_card);
+    // Use ASSERT instead of EXPECT to abort the current function (test)
+    // because adding and removing additional cards in an already incorrect
+    // hand makes no sense.
+    ASSERT_EQ(expected_hand, player_hand.get_cards());
+
+    player_hand.add_card(cards[1][0], err);
+    player_hand.add_card(cards[3][0], err);
+    player_hand.add_card(cards[7][0], err);
+
+    to_remove = cards[1][1];
+    removed_card = cards[1][1];
+    EXPECT_FALSE(player_hand.remove_card(to_remove->get_id(), removed_card, err));
+    expected_hand = {cards[1][0], cards[3][0], cards[7][0]};
+    EXPECT_EQ(nullptr, removed_card);
+    EXPECT_EQ(expected_hand, player_hand.get_cards());
+}
+
+// Removing the final card from a hand must succeed
+TEST_F(HandTest, RemoveAllCards) {
+    player_hand.add_card(cards[1][0], err);
+
+    card* to_remove = cards[1][0];
+    card* removed_card = nullptr;
+    EXPECT_TRUE(player_hand.remove_card(to_remove->get_id(), removed_card, err));
+    std::vector<card*> expected_hand = {};
+    EXPECT_EQ(to_remove, removed_card);
+    EXPECT_EQ(expected_hand, player_hand.get_cards());
+}
+
+// Removing several cards of different values from a hand of seven cards must succeed
+TEST_F(HandTest, RemoveManyCards) {
+    player_hand.add_card(cards[1][0], err);
+    player_hand.add_card(cards[1][1], err);
+    player_hand.add_card(cards[1][2], err);
+    player_hand.add_card(cards[3][0], err);
+    player_hand.add_card(cards[3][1], err);
+    player_hand.add_card(cards[7][0], err);
+
+    card* to_remove = cards[1][0];
+    card* removed_card = nullptr;
+    EXPECT_TRUE(player_hand.remove_card(to_remove->get_id(), removed_card, err));
+    std::vector<card*> expected_hand = {cards[1][1], cards[1][2], cards[3][0],
+                                        cards[3][1], cards[7][0]};
+    EXPECT_EQ(to_remove, removed_card);
+    ASSERT_EQ(expected_hand, player_hand.get_cards());
+
+    to_remove = cards[3][0];
+    removed_card = nullptr;
+    EXPECT_TRUE(player_hand.remove_card(to_remove->get_id(), removed_card, err));
+    expected_hand = {cards[1][1], cards[1][2], cards[3][1], cards[7][0]};
+    EXPECT_EQ(to_remove, removed_card);
+    ASSERT_EQ(expected_hand, player_hand.get_cards());
+
+    to_remove = cards[7][0];
+    removed_card = nullptr;
+    EXPECT_TRUE(player_hand.remove_card(to_remove->get_id(), removed_card, err));
+    expected_hand = {cards[1][1], cards[1][2], cards[3][1]};
+    EXPECT_EQ(to_remove, removed_card);
+    EXPECT_EQ(expected_hand, player_hand.get_cards());
+}
+
+// Removing several cards of the same value from a hand of seven cards must succeed
+TEST_F(HandTest, RemoveManyDuplicateCards) {
+    player_hand.add_card(cards[1][0], err);
+    player_hand.add_card(cards[1][1], err);
+    player_hand.add_card(cards[1][2], err);
+    player_hand.add_card(cards[3][0], err);
+    player_hand.add_card(cards[3][1], err);
+    player_hand.add_card(cards[7][0], err);
+
+    card* to_remove = cards[3][0];
+    card* removed_card = nullptr;
+    EXPECT_TRUE(player_hand.remove_card(to_remove->get_id(), removed_card, err));
+    std::vector<card*> expected_hand = {cards[1][0], cards[1][1], cards[1][2],
+                                        cards[3][1], cards[7][0]};
+    EXPECT_EQ(to_remove, removed_card);
+    ASSERT_EQ(expected_hand, player_hand.get_cards());
+
+    to_remove = cards[3][1];
+    removed_card = nullptr;
+    EXPECT_TRUE(player_hand.remove_card(to_remove->get_id(), removed_card, err));
+    expected_hand = {cards[1][0], cards[1][1], cards[1][2], cards[7][0]};
+    EXPECT_EQ(to_remove, removed_card);
+    EXPECT_EQ(expected_hand, player_hand.get_cards());
+}
+
+// The score of a hand with a single card of value one must be equal to 1
+TEST_F(HandTest, ScoreOneCard) {
+    player_hand.add_card(cards[1][0], err);
+    EXPECT_EQ(1, player_hand.get_score());
+}
+
+// The score of a hand with a single Wizard card must be equal to 10
+TEST_F(HandTest, ScoreWizard) {
+    player_hand.add_card(cards[7][0], err);
+    EXPECT_EQ(10, player_hand.get_score());
+}
+
+// The score of an empty hand must be zero
+TEST_F(HandTest, ScoreNoCards) {
+    EXPECT_EQ(0, player_hand.get_score());
+}
+
+// Each addition of a card must increase the score by that card's value
+TEST_F(HandTest, ScoreManyCards) {
+    player_hand.add_card(cards[1][0], err);
+    ASSERT_EQ(1, player_hand.get_score());
+    player_hand.add_card(cards[3][0], err);
+    ASSERT_EQ(4, player_hand.get_score());
+    player_hand.add_card(cards[7][0], err);
+    EXPECT_EQ(14, player_hand.get_score());
+}
+
+// Each addition of a card must increase the score by that card's value even
+// if several cards have the same value
+TEST_F(HandTest, ScoreManyCardsWithDuplicates) {
+    player_hand.add_card(cards[1][0], err);
+    ASSERT_EQ(1, player_hand.get_score());
+    player_hand.add_card(cards[1][1], err);
+    ASSERT_EQ(1, player_hand.get_score());
+    player_hand.add_card(cards[1][2], err);
+    ASSERT_EQ(1, player_hand.get_score());
+    player_hand.add_card(cards[3][0], err);
+    ASSERT_EQ(4, player_hand.get_score());
+    player_hand.add_card(cards[3][1], err);
+    ASSERT_EQ(4, player_hand.get_score());
+    player_hand.add_card(cards[7][0], err);
+    EXPECT_EQ(14, player_hand.get_score());
+}
+
+// A hand of one card must have count 1
+TEST_F(HandTest, CountOneCard) {
+    player_hand.add_card(cards[1][0], err);
+    EXPECT_EQ(1, player_hand.get_nof_cards());
+}
+
+// An empty hand must have count 0
+TEST_F(HandTest, CountNoCards) {
+    EXPECT_EQ(0, player_hand.get_nof_cards());
+}
+
+// Each addition of a card must increase the count by 1
+TEST_F(HandTest, CountManyCards) {
+    player_hand.add_card(cards[1][0], err);
+    ASSERT_EQ(1, player_hand.get_nof_cards());
+    player_hand.add_card(cards[3][0], err);
+    ASSERT_EQ(2, player_hand.get_nof_cards());
+    player_hand.add_card(cards[7][0], err);
+    EXPECT_EQ(3, player_hand.get_nof_cards());
+}
+
+// Each addition of a card must increase the count by 1 even if several cards
+// have the same value
+TEST_F(HandTest, CountManyCardsWithDuplicates) {
+    player_hand.add_card(cards[1][0], err);
+    ASSERT_EQ(1, player_hand.get_nof_cards());
+    player_hand.add_card(cards[1][1], err);
+    ASSERT_EQ(2, player_hand.get_nof_cards());
+    player_hand.add_card(cards[1][2], err);
+    ASSERT_EQ(3, player_hand.get_nof_cards());
+    player_hand.add_card(cards[3][0], err);
+    ASSERT_EQ(4, player_hand.get_nof_cards());
+    player_hand.add_card(cards[3][1], err);
+    ASSERT_EQ(5, player_hand.get_nof_cards());
+    player_hand.add_card(cards[7][0], err);
+    EXPECT_EQ(6, player_hand.get_nof_cards());
+}
diff --git a/unit-tests/hand.cpp b/unit-tests/hand.cpp
index 01a1e4d8f78859da7561887bf78f558a4e6c46ce..f261bbf13f0b90d443a7b56c27d2434596a6775d 100644
--- a/unit-tests/hand.cpp
+++ b/unit-tests/hand.cpp
@@ -6,7 +6,7 @@
 #include "../src/common/game_state/player/hand.h"
 
 
-/* A test fixture allows to reuse the same configuration of objects for all
+/* A test fixture allows us to reuse the same configuration of objects for all
  * tests in a test suite. The name of the fixture must match the test suite.
  *
  * For each test defined with TEST_F(), googletest will create a fresh test