diff --git a/.gitignore b/.gitignore
index 0be8e4283ad45c48e0ffceda0c678ae136003a49..1cfc896ff4d08fe9b8df2a9b2a1a662f566bebf1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -98,4 +98,8 @@ fabric.properties
 hs_err_pid*
 
 .gradle
-gradle
\ No newline at end of file
+gradle
+
+test.json
+oof
+hello.jar
\ No newline at end of file
diff --git a/.idea/artifacts/tester_jar.xml b/.idea/artifacts/tester_jar.xml
new file mode 100644
index 0000000000000000000000000000000000000000..6381260227701c7d13b2f83c27bc28b4cf51fa56
--- /dev/null
+++ b/.idea/artifacts/tester_jar.xml
@@ -0,0 +1,15 @@
+<component name="ArtifactManager">
+  <artifact type="jar" name="tester:jar">
+    <output-path>$PROJECT_DIR$/out/artifacts/tester_jar</output-path>
+    <root id="archive" name="tester.jar">
+      <element id="module-output" name="tester.main" />
+      <element id="extracted-dir" path="$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.google.code.gson/gson/2.8.6/9180733b7df8542621dc12e21e87557e8c99b8cb/gson-2.8.6.jar" path-in-jar="/" />
+      <element id="extracted-dir" path="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.junit.jupiter/junit-jupiter-engine/5.6.0/83c9e737f6015d9e00029b9b1d51e952a884b8f9/junit-jupiter-engine-5.6.0.jar" path-in-jar="/" />
+      <element id="extracted-dir" path="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.junit.platform/junit-platform-engine/1.6.0/a3a6ec96c010875444b3ca31828108093758ec00/junit-platform-engine-1.6.0.jar" path-in-jar="/" />
+      <element id="extracted-dir" path="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.opentest4j/opentest4j/1.2.0/28c11eb91f9b6d8e200631d46e20a7f407f2a046/opentest4j-1.2.0.jar" path-in-jar="/" />
+      <element id="extracted-dir" path="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.apiguardian/apiguardian-api/1.1.0/fc9dff4bb36d627bdc553de77e1f17efd790876c/apiguardian-api-1.1.0.jar" path-in-jar="/" />
+      <element id="extracted-dir" path="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.junit.jupiter/junit-jupiter-api/5.6.0/f29e6318333d2303ce4965c9819cfad08de7d1e5/junit-jupiter-api-5.6.0.jar" path-in-jar="/" />
+      <element id="extracted-dir" path="$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.junit.platform/junit-platform-commons/1.6.0/b0a75795cf03841d4f9cc54099557baffc11c727/junit-platform-commons-1.6.0.jar" path-in-jar="/" />
+    </root>
+  </artifact>
+</component>
\ No newline at end of file
diff --git a/build.gradle b/build.gradle
index b3beeec6b85c7866a90c42054a1f13f751aeaebe..e7a370cafb70cca766b48998a94c137c4f213e24 100644
--- a/build.gradle
+++ b/build.gradle
@@ -3,6 +3,9 @@ plugins {
     id 'java'
 }
 
+sourceCompatibility = 10
+targetCompatibility = 10
+
 group 'projlab.tester'
 version '1.0-SNAPSHOT'
 
@@ -10,6 +13,12 @@ repositories {
     mavenCentral()
 }
 
+jar {
+    manifest {
+        from "src/main/java/META-INF/MANIFEST.MF"
+    }
+}
+
 dependencies {
     testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.0'
     testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'
diff --git a/src/main/java/META-INF/MANIFEST.MF b/src/main/java/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000000000000000000000000000000000..501fcf5f4acba222f935a3700bdddfe615057f77
--- /dev/null
+++ b/src/main/java/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Main-Class: tester.Main
+
diff --git a/src/main/java/tester/Main.java b/src/main/java/tester/Main.java
index f0472832e26c33d798ea83f97838fea4843c5a56..bef72f9391701e983b89331e788d707ca0662916 100644
--- a/src/main/java/tester/Main.java
+++ b/src/main/java/tester/Main.java
@@ -4,6 +4,12 @@ import com.google.gson.Gson;
 
 import java.io.FileNotFoundException;
 import java.io.FileReader;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.concurrent.atomic.AtomicBoolean;
 
 public class Main {
     public static void main(String[] args) throws FileNotFoundException {
@@ -16,6 +22,148 @@ public class Main {
 
         TestCase test = gson.fromJson(new FileReader(args[1]), TestCase.class);
 
-        System.out.println(test.files);
+        if (System.getProperty("os.name").toLowerCase().contains("win")){
+            try {
+                ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/c", "@chcp", "65001>nul").inheritIO();
+                Process p = pb.start();
+                p.waitFor();
+                System.setOut(new PrintStream(System.out, true, StandardCharsets.UTF_8));
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+
+        Process proc;
+        try {
+            proc = Runtime.getRuntime().exec(String.format("java -jar %s", args[0]));
+        } catch (Exception e) {
+            System.out.print("❌ ");
+            System.out.printf("Nem sikerület elindítani a folyamatot, kérlek ellenőrizd, hogy tesztelendő program tényleg itt van-e: \"%s\"\n", args[0]);
+            System.exit(1);
+            return;
+        }
+        
+        var in = proc.getOutputStream();
+        var out = proc.getInputStream();
+
+        try {
+            in.write(test.input.getBytes(StandardCharsets.UTF_8));
+            in.flush();
+            in.close();
+        } catch (Exception e) {
+            System.out.print("❌ ");
+            System.out.println("A program nem fogadott annyi inputot, amennyi meg volt adva.");
+            System.exit(1);
+            return;
+        }
+
+        try {
+            proc.waitFor();
+        } catch (Exception e) {
+            System.out.print("❌ ");
+            System.out.println("Nem sikerült a programnak helyesen bezáródni.");
+            System.exit(1);
+            return;
+        }
+        
+        String o = "";
+        try {
+            byte[] by = out.readAllBytes();
+            o = new String(by, StandardCharsets.UTF_8);
+        } catch (Exception e){
+            System.out.print("❌ ");
+            System.out.println("Nem sikerült kiolvasni a program outputját.");
+        }
+
+        System.out.println("--------------");
+        System.out.println("Kimenet tesztelése");
+        System.out.println();
+
+        AtomicBoolean error = new AtomicBoolean(compareStrings(o, test.output));
+        if (!error.get()) {
+            System.out.print("✔️ ");
+            System.out.println("Siker.");
+        }
+
+        test.files.forEach((f, e) -> {
+            System.out.println();
+            System.out.println();
+            System.out.println("--------------");
+            System.out.printf("File: %s\n", f);
+            System.out.println();
+            try {
+                String got = Files.readString(Path.of(f));
+                boolean er = compareStrings(got, e);
+                if (er) {
+                    error.set(true);
+                } else {
+                    System.out.print("✔️ ");
+                    System.out.println("Siker.");
+                }
+            } catch (Exception exception) {
+                error.set(true);
+                System.out.print("❌ ");
+                System.out.printf("Nem sikerült megnyitni a \"%s\" fájlt.\n", f);
+            }
+        });
+
+        System.out.println();
+        System.out.println("--------------");
+
+
+        if (error.get()) {
+            System.out.print("\uD83D\uDD25 ");
+        } else {
+            System.out.print("✅ ");
+        }
+        
+        System.out.print("A program tesztelése siker");
+        if (error.get()) {
+            System.out.print("telenül");
+        } else {
+            System.out.print("esen");
+        }
+        System.out.println(" végződött.");
+        
+        if (error.get()) {
+            System.exit(1);
+        }
+    }
+    
+    private static boolean compareStrings(String gotOut, String expected) {
+        String[] expectedLines = expected.split("\n");
+        String[] gotLines = gotOut.split("\n");
+
+        boolean error = false;
+        int i = 0;
+        for (; i < expectedLines.length; i++) {
+            String exp = expectedLines[i].trim();
+            if (gotLines.length <= i) {
+                error = true;
+                System.out.print("❌ ");
+                System.out.println("A program rövidebb kimenetet produkált, mint az elvárt.");
+                System.out.printf("sor %d:\n", i);
+                System.out.printf("  várt: %s\n", exp);
+            } else {
+                String got = gotLines[i].trim();
+                if (!exp.equals(got)) {
+                    error = true;
+                    System.out.print("❌ ");
+                    System.out.printf("sor %d:\n", i);
+                    System.out.printf("  várt: %s\n", exp);
+                    System.out.printf("kapott: %s\n", got);
+                }
+            }
+        }
+
+        for (; i < gotLines.length; i++) {
+            error = true;
+            String got = gotLines[i].trim();
+            System.out.print("❌ ");
+            System.out.println("A program hosszabb kimenetet produkált, mint az elvárt.");
+            System.out.printf("sor %d:\n", i);
+            System.out.printf("kapott: %s\n", got);
+        }
+        return error;
     }
 }