diff --git a/src/main/java/mi/hdm/filesystem/CSVParser.java b/src/main/java/mi/hdm/filesystem/CSVParser.java
index a5362801f9e6f1cc5eee0cb5b09fc0a7ff47a784..59fa405cd904c649ca39b6174822fe224faa6148 100644
--- a/src/main/java/mi/hdm/filesystem/CSVParser.java
+++ b/src/main/java/mi/hdm/filesystem/CSVParser.java
@@ -19,35 +19,39 @@ public class CSVParser {
     private static final Logger log = LogManager.getLogger(CSVParser.class);
 
     /**
-     * @param filepath Path where the CSV-file is located
+     * @param filepath Path where the CSV file is located
      * @param split    The character that the columns are split by
-     * @param extract  Names of the columns to extract
+     * @param extract  Names of the columns to extract with extract[0] being the name of the ingredient
      * @return list of all ingredients inside the csv
      */
-    public List<Ingredient> getIngredientsFromCSV(String filepath, char split, String... extract) {
-        log.info("Reading ingredients from CSV: {}", filepath);
-        try {
-            BufferedReader reader = new BufferedReader(new FileReader(filepath));
+    public List<Ingredient> getIngredientsFromCSV(String filepath, char split, String... extract) throws IOException {
+        log.info("Trying to read ingredients from CSV: {}", filepath);
+
+        //try-block with automatic resource management
+        try (BufferedReader reader = new BufferedReader(new FileReader(filepath))) {
             final String header = reader.readLine(); //read first line of CSV
-            int[] indexes = getColumnIndexes(header, split, extract);
+            final int[] indexes = getColumnIndexes(header, split, extract);
 
             //Loop through lines
-            List<Ingredient> ingredients = reader.lines()
+            final List<Ingredient> ingredients = reader.lines()
                     .map(line -> getIngredientFromLine(line, split, indexes))
                     .toList();
-            reader.close();
-            log.info("Found and parsed {} ingredients.", ingredients.size());
+            if (ingredients.size() > 0) {
+                log.info("Found and parsed {} ingredients.", ingredients.size());
+            } else {
+                log.warn("No ingredients found in CSV, returning empty list.");
+            }
             return ingredients;
+
         } catch (FileNotFoundException fileNotFoundException) {
-            Path filename = Path.of(filepath).getFileName();
+            final Path filename = Path.of(filepath).getFileName();
             log.error("File '{}' not found at specified filepath: {}.", filename, filepath);
             fileNotFoundException.printStackTrace();
+            throw fileNotFoundException;
         } catch (IOException io) {
             log.error("An error occurred while reading CSV: {}", filepath);
-            io.printStackTrace();
+            throw io;
         }
-        log.warn("No ingredients found in CSV, returning empty list.");
-        return List.of();
     }
 
     private Ingredient getIngredientFromLine(String line, char split, int[] idx) throws NumberFormatException {
@@ -56,21 +60,20 @@ public class CSVParser {
         final Measurement measurement = Measurement.GRAM;
         final List<String> splitLine = splitLine(line, split);
 
-        String name = splitLine.get(idx[0]);
-        List<Double> nutrition = new ArrayList<>();
+        final String recipeName = splitLine.get(idx[0]);
+        final List<Double> nutrition = new ArrayList<>();
 
         for (int i = 1; i < idx.length; i++) {
             String element = splitLine.get(idx[i]).split(" ")[0];
             nutrition.add(parseNumberFromString(element));
         }
 
-        NutritionTable nutritionTable = new NutritionTable(nutrition);
-
-        return new Ingredient(measurement, name, nutritionTable);
+        final NutritionTable nutritionTable = new NutritionTable(nutrition);
+        return new Ingredient(measurement, recipeName, nutritionTable);
     }
 
     private int[] getColumnIndexes(String header, char splitChar, String... extract) throws InvalidPropertiesFormatException {
-        final String[] split = header.split(String.valueOf(splitChar)); //read first line of CSV
+        final String[] split = header.split(String.valueOf(splitChar)); //split header of CSV
         //find indexes of columns that need to be extracted
         int[] colIndexes = new int[extract.length];
         for (int i = 0; i < extract.length; i++) {
@@ -117,13 +120,18 @@ public class CSVParser {
         return Double.parseDouble(numValue.toString());
     }
 
+    /**
+     * Split a line of CSV in its individual tokens based on a character while accounting for strings inside of columns
+     *
+     * @return list of tokens inside the provided line
+     */
     private List<String> splitLine(String line, char splitChar) {
-        List<String> output = new ArrayList<>();
+        final List<String> output = new ArrayList<>();
         StringBuilder builder = new StringBuilder();
 
         boolean inQuotes = false;
         for (int i = 0; i < line.length(); i++) {
-            char c = line.charAt(i);
+            final char c = line.charAt(i);
             if (c == '"') {
                 inQuotes = !inQuotes;
             } else if (c == splitChar && !inQuotes) {
diff --git a/src/main/java/mi/hdm/recipes/RecipeSearch.java b/src/main/java/mi/hdm/recipes/RecipeSearch.java
index f23abdac42727b319de00a26d37b0db78789df83..70b689bf53c23cd38c4589df1444ff186b996e23 100644
--- a/src/main/java/mi/hdm/recipes/RecipeSearch.java
+++ b/src/main/java/mi/hdm/recipes/RecipeSearch.java
@@ -1,10 +1,14 @@
 package mi.hdm.recipes;
 
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
 import java.util.ArrayList;
 import java.util.List;
 
 public class RecipeSearch {
     private final List<Recipe> recipesToSearch;
+    private static final Logger log = LogManager.getLogger(RecipeSearch.class);
 
     public RecipeSearch (List<Recipe> recipesToSearch) {
         this.recipesToSearch = recipesToSearch;
@@ -17,8 +21,11 @@ public class RecipeSearch {
      * @param query a String with keywords to search for
      * @return a list of Recipes which contain one or several of the keywords in its name or its ingredients
      */
-    public List<Recipe> searchByQuery(String query) { //TODO: filter out chars like ! ? . : etc
-        if (query == null || query.isBlank()) return recipesToSearch;
+    public List<Recipe> searchByQuery(String query) {
+        if (query == null) return recipesToSearch;
+        query = query.replaceAll("[.,!+?;-]", " ").trim();
+        if (query.isBlank()) return recipesToSearch;
+        log.debug("Searching for {}", query);
 
         List<Recipe> result = new ArrayList<>();
         String[] split = query.split(" ");  //split String into separate words and put them into a String Array
diff --git a/src/test/java/mi/hdm/filesystem/CSVParserTest.java b/src/test/java/mi/hdm/filesystem/CSVParserTest.java
index 63d2e109f949f35b52c3305f12362f6c67ae7344..f872a7b40eb3a3b7dfb224fea06044ba19e01262 100644
--- a/src/test/java/mi/hdm/filesystem/CSVParserTest.java
+++ b/src/test/java/mi/hdm/filesystem/CSVParserTest.java
@@ -1,5 +1,6 @@
 package mi.hdm.filesystem;
 
+import jdk.jfr.Description;
 import mi.hdm.recipes.Ingredient;
 import mi.hdm.recipes.Measurement;
 import mi.hdm.recipes.NutritionTable;
@@ -22,6 +23,7 @@ class CSVParserTest {
 
     @BeforeAll
     public static void setupAll() throws NoSuchMethodException {
+        //make private methods accessible for testing
         splitLine = underTest.getClass().getDeclaredMethod("splitLine", String.class, char.class);
         splitLine.setAccessible(true);
         getColIdxs = underTest.getClass().getDeclaredMethod("getColumnIndexes", String.class, char.class, String[].class);
@@ -29,6 +31,7 @@ class CSVParserTest {
     }
 
     @Test
+    @Description("Test if splitting a line in the CSV file works properly")
     public void testSplitLine() throws Exception {
         String line = "1,\"Nuts, pecans\",100 g,691,72g";
         List<String> expected = List.of("1", "Nuts, pecans", "100 g", "691", "72g");
@@ -39,6 +42,7 @@ class CSVParserTest {
     }
 
     @Test
+    @Description("Tests, if the columns to be extracted are found in the correct place and assigned with the correct index")
     public void testGetColumnIndexes() throws Exception {
         String header = ",name,calories,total_fat,saturated_fat,cholesterol,sodium";
         String[] extract = new String[]{"name", "sodium"};
@@ -49,6 +53,7 @@ class CSVParserTest {
     }
 
     @Test
+    @Description("Test, if getting a list of ingredients from CSV works")
     public void testGetIngredientsFromCSV() throws Exception {
         String relative = "/data/testdata.csv";
         URL resourceUrl = underTest.getClass().getResource(relative);
diff --git a/src/test/java/mi/hdm/recipes/RecipeSearchTest.java b/src/test/java/mi/hdm/recipes/RecipeSearchTest.java
index 605241a127e4aa5b78ab7c324b592d0e024c9d60..f29d421ab1091160c37bbf790b1d94e3c5b7dc81 100644
--- a/src/test/java/mi/hdm/recipes/RecipeSearchTest.java
+++ b/src/test/java/mi/hdm/recipes/RecipeSearchTest.java
@@ -2,6 +2,9 @@ package mi.hdm.recipes;
 
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.NullAndEmptySource;
+import org.junit.jupiter.params.provider.ValueSource;
 
 import java.util.List;
 
@@ -23,18 +26,18 @@ class RecipeSearchTest {
         underTest = new RecipeSearch(recipes);
     }
 
-    @Test
-    public void testSearchByEmptyQuery() {
-        assertEquals(recipes, underTest.searchByQuery(null));
-        assertEquals(recipes, underTest.searchByQuery(""));
-        assertEquals(recipes, underTest.searchByQuery("   \n"));
+    @ParameterizedTest
+    @NullAndEmptySource
+    @ValueSource(strings = {"   \n", ".", "!", "..."})
+    public void testSearchByEmptyQuery(String input) {
+        assertEquals(recipes, underTest.searchByQuery(input));
     }
 
-    @Test
-    public void testSearchByNameQuery() {
+    @ParameterizedTest
+    @ValueSource(strings = {"valid", "valid!", "...valid"})
+    public void testSearchByNameQuery(String query) {
         //given
         List<Recipe> expected = List.of(r1);
-        String query = "valid";
 
         //when
         List<Recipe> result = underTest.searchByQuery(query);
@@ -56,10 +59,10 @@ class RecipeSearchTest {
         assertEquals(expected, result);
     }
 
-    @Test
-    public void testSearchByEmptyCategories() {
-        assertEquals(recipes, underTest.searchByCategory(List.of()));
-        assertEquals(recipes, underTest.searchByCategory(null));
+    @ParameterizedTest
+    @NullAndEmptySource
+    public void testSearchByEmptyCategories(List<Category> input) {
+        assertEquals(recipes, underTest.searchByCategory(input));
     }
 
     @Test