diff --git a/lisa-utils/src/test/scala/lisa/utils/PrinterTest.scala b/lisa-utils/src/test/scala/lisa/utils/PrinterTest.scala
index d03d2b579a82e17b427ee182aa0206b9719b8b7f..f1757835bbd8da9faa33278e0fa41d8aa59d8edd 100644
--- a/lisa-utils/src/test/scala/lisa/utils/PrinterTest.scala
+++ b/lisa-utils/src/test/scala/lisa/utils/PrinterTest.scala
@@ -1,8 +1,10 @@
 package lisa.utils
 
 import lisa.kernel.fol.FOL.*
-import lisa.utils.Printer.*
+import lisa.kernel.proof.SequentCalculus.Sequent
+import lisa.utils.Helpers.*
 import lisa.utils.Parser
+import lisa.utils.Printer.*
 import org.scalatest.funsuite.AnyFunSuite
 
 import scala.language.adhocExtensions
@@ -37,4 +39,198 @@ class PrinterTest extends AnyFunSuite with TestUtils {
     assert(Parser.printFormula(PredicateFormula(ConstantPredicateLabel("f", 3), Seq(x, y, z))) == "f(?x, ?y, ?z)")
   }
 
+  test("constant") {
+    assert(Parser.printTerm(FunctionTerm(cx, Seq())) == "x")
+  }
+
+  test("variable") {
+    assert(Parser.printTerm(VariableTerm(x)) == "?x")
+  }
+
+  test("constant function application") {
+    assert(Parser.printTerm(FunctionTerm(f1, Seq(cx))) == "f(x)")
+    assert(Parser.printTerm(FunctionTerm(f2, Seq(cx, cy))) == "f(x, y)")
+    assert(Parser.printTerm(FunctionTerm(f3, Seq(cx, cy, cz))) == "f(x, y, z)")
+
+    assert(Parser.printTerm(FunctionTerm(f1, Seq(x))) == "f(?x)")
+    assert(Parser.printTerm(FunctionTerm(f2, Seq(x, y))) == "f(?x, ?y)")
+    assert(Parser.printTerm(FunctionTerm(f3, Seq(x, y, z))) == "f(?x, ?y, ?z)")
+  }
+
+  test("schematic function application") {
+    assert(Parser.printTerm(FunctionTerm(sf1, Seq(cx))) == "?f(x)")
+    assert(Parser.printTerm(FunctionTerm(sf2, Seq(cx, cy))) == "?f(x, y)")
+    assert(Parser.printTerm(FunctionTerm(sf3, Seq(cx, cy, cz))) == "?f(x, y, z)")
+
+    assert(Parser.printTerm(FunctionTerm(sf1, Seq(x))) == "?f(?x)")
+    assert(Parser.printTerm(FunctionTerm(sf2, Seq(x, y))) == "?f(?x, ?y)")
+    assert(Parser.printTerm(FunctionTerm(sf3, Seq(x, y, z))) == "?f(?x, ?y, ?z)")
+  }
+
+  test("nested function application") {
+    assert(Parser.printTerm(FunctionTerm(sf2, Seq(FunctionTerm(sf1, Seq(x)), y))) == "?f(?f(?x), ?y)")
+  }
+
+  test("0-ary predicate") {
+    assert(Parser.printFormula(PredicateFormula(ConstantPredicateLabel("a", 0), Seq())) == "a")
+  }
+
+  test("predicate application") {
+    assert(Parser.printFormula(PredicateFormula(ConstantPredicateLabel("p", 3), Seq(cx, cy, cz))) == "p(x, y, z)")
+    assert(Parser.printFormula(PredicateFormula(ConstantPredicateLabel("p", 3), Seq(x, y, z))) == "p(?x, ?y, ?z)")
+  }
+
+  test("equality") {
+    assert(Parser.printFormula(PredicateFormula(equality, Seq(cx, cx))) == "x = x")
+    assert(Parser.printFormula(ConnectorFormula(And, Seq(a, PredicateFormula(equality, Seq(x, x))))) == "a ∧ ?x = ?x")
+  }
+
+  test("unicode connectors") {
+    assert(Parser.printFormula(ConnectorFormula(Neg, Seq(a))) == "¬a")
+    assert(Parser.printFormula(ConnectorFormula(And, Seq(a, b))) == "a ∧ b")
+    assert(Parser.printFormula(ConnectorFormula(Or, Seq(a, b))) == "a ∨ b")
+    assert(Parser.printFormula(ConnectorFormula(Implies, Seq(a, b))) == "a ⇒ b")
+    assert(Parser.printFormula(ConnectorFormula(Iff, Seq(a, b))) == "a ↔ b")
+  }
+
+  test("connector associativity") {
+    assert(Parser.printFormula(ConnectorFormula(And, Seq(ConnectorFormula(And, Seq(a, b)), c))) == "a ∧ b ∧ c")
+    assert(Parser.printFormula(ConnectorFormula(Or, Seq(ConnectorFormula(Or, Seq(a, b)), c))) == "a ∨ b ∨ c")
+  }
+
+  test("connector priority") {
+    // a ∨ (b ∧ c)
+    assert(Parser.printFormula(ConnectorFormula(Or, Seq(a, ConnectorFormula(And, Seq(b, c))))) == "a ∨ b ∧ c")
+    // (a ∧ b) ∨ c
+    assert(Parser.printFormula(ConnectorFormula(Or, Seq(ConnectorFormula(And, Seq(a, b)), c))) == "a ∧ b ∨ c")
+
+    // (a ∧ b) => c
+    assert(Parser.printFormula(ConnectorFormula(Implies, Seq(ConnectorFormula(And, Seq(a, b)), c))) == "a ∧ b ⇒ c")
+    // a => (b ∧ c)
+    assert(Parser.printFormula(ConnectorFormula(Implies, Seq(a, ConnectorFormula(And, Seq(b, c))))) == "a ⇒ b ∧ c")
+    // (a ∨ b) => c
+    assert(Parser.printFormula(ConnectorFormula(Implies, Seq(ConnectorFormula(Or, Seq(a, b)), c))) == "a ∨ b ⇒ c")
+    // a => (b ∨ c)
+    assert(Parser.printFormula(ConnectorFormula(Implies, Seq(a, ConnectorFormula(Or, Seq(b, c))))) == "a ⇒ b ∨ c")
+
+    // (a ∧ b) <=> c
+    assert(Parser.printFormula(ConnectorFormula(Iff, Seq(ConnectorFormula(And, Seq(a, b)), c))) == "a ∧ b ↔ c")
+    // a <=> (b ∧ c)
+    assert(Parser.printFormula(ConnectorFormula(Iff, Seq(a, ConnectorFormula(And, Seq(b, c))))) == "a ↔ b ∧ c")
+    // (a ∨ b) <=> c
+    assert(Parser.printFormula(ConnectorFormula(Iff, Seq(ConnectorFormula(Or, Seq(a, b)), c))) == "a ∨ b ↔ c")
+    // a <=> (b ∨ c)
+    assert(Parser.printFormula(ConnectorFormula(Iff, Seq(a, ConnectorFormula(Or, Seq(b, c))))) == "a ↔ b ∨ c")
+  }
+
+  test("connector parentheses") {
+    assert(Parser.printFormula(ConnectorFormula(And, Seq(ConnectorFormula(Or, Seq(a, b)), c))) == "(a ∨ b) ∧ c")
+    assert(Parser.printFormula(ConnectorFormula(And, Seq(a, ConnectorFormula(Or, Seq(b, c))))) == "a ∧ (b ∨ c)")
+  }
+
+  test("quantifiers") {
+    assert(Parser.printFormula(BinderFormula(Forall, VariableLabel("x"), PredicateFormula(ConstantPredicateLabel("p", 0), Seq()))) == "∀ ?x. p")
+    assert(Parser.printFormula(BinderFormula(Exists, VariableLabel("x"), PredicateFormula(ConstantPredicateLabel("p", 0), Seq()))) == "∃ ?x. p")
+    assert(Parser.printFormula(BinderFormula(ExistsOne, VariableLabel("x"), PredicateFormula(ConstantPredicateLabel("p", 0), Seq()))) == "∃! ?x. p")
+  }
+
+  test("nested quantifiers") {
+    assert(Parser.printFormula(BinderFormula(Forall, x, BinderFormula(Exists, y, BinderFormula(ExistsOne, z, a)))) == "∀ ?x. ∃ ?y. ∃! ?z. a")
+  }
+
+  test("quantifier parentheses") {
+    assert(Parser.printFormula(BinderFormula(Forall, x, ConnectorFormula(And, Seq(b, a)))) == "∀ ?x. b ∧ a")
+    assert(
+      Parser.printFormula(
+        BinderFormula(
+          Forall,
+          x,
+          ConnectorFormula(And, Seq(PredicateFormula(ConstantPredicateLabel("p", 1), Seq(x)), PredicateFormula(ConstantPredicateLabel("q", 1), Seq(x))))
+        )
+      ) == "∀ ?x. p(?x) ∧ q(?x)"
+    )
+
+    assert(Parser.printFormula(ConnectorFormula(And, Seq(BinderFormula(Forall, x, b), a))) == "(∀ ?x. b) ∧ a")
+
+    assert(
+      Parser.printFormula(
+        ConnectorFormula(
+          And,
+          Seq(
+            BinderFormula(Forall, VariableLabel("x"), PredicateFormula(ConstantPredicateLabel("p", 1), Seq(x))),
+            PredicateFormula(ConstantPredicateLabel("q", 1), Seq(x))
+          )
+        )
+      ) == "(∀ ?x. p(?x)) ∧ q(?x)"
+    )
+
+    assert(Parser.printFormula(ConnectorFormula(Or, Seq(ConnectorFormula(And, Seq(a, BinderFormula(Forall, x, b))), a))) == "a ∧ (∀ ?x. b) ∨ a")
+    assert(Parser.printFormula(ConnectorFormula(And, Seq(ConnectorFormula(And, Seq(a, BinderFormula(Forall, x, b))), a))) == "a ∧ (∀ ?x. b) ∧ a")
+  }
+
+  test("complex formulas with connectors") {
+    assert(Parser.printFormula(ConnectorFormula(Neg, Seq(ConnectorFormula(Or, Seq(a, b))))) == "¬(a ∨ b)")
+    assert(Parser.printFormula(ConnectorFormula(Neg, Seq(ConnectorFormula(Neg, Seq(a))))) == "¬¬a")
+    assert(Parser.printFormula(ConnectorFormula(Neg, Seq(ConnectorFormula(Neg, Seq(ConnectorFormula(And, Seq(a, b))))))) == "¬¬(a ∧ b)")
+    assert(Parser.printFormula(ConnectorFormula(And, Seq(ConnectorFormula(And, Seq(ConnectorFormula(Neg, Seq(a)), ConnectorFormula(Neg, Seq(b)))), ConnectorFormula(Neg, Seq(c))))) == "¬a ∧ ¬b ∧ ¬c")
+  }
+
+  test("complex formulas") {
+    assert(Parser.printFormula(BinderFormula(Forall, x, PredicateFormula(equality, Seq(x, x)))) == "∀ ?x. ?x = ?x")
+  }
+
+  test("sequent") {
+    val forallEq = BinderFormula(Forall, x, PredicateFormula(equality, Seq(x, x)))
+    assert(Parser.printSequent(Sequent(Set(), Set(forallEq))) == "⊢ ∀ ?x. ?x = ?x")
+    assert(Parser.printSequent(Sequent(Set(forallEq), Set(forallEq))) == "∀ ?x. ?x = ?x ⊢ ∀ ?x. ?x = ?x")
+    val existsXEq = BinderFormula(Exists, x, PredicateFormula(equality, Seq(x, x)))
+    assert(Parser.printSequent(Sequent(Set(forallEq), Set(existsXEq))) == "∀ ?x. ?x = ?x ⊢ ∃ ?x. ?x = ?x")
+  }
+
+  // warning: this test might be flaky because formula order is not fixed in sequents but fixed in the string representation
+  test("sequent with multiple formulas") {
+    val forallEq = BinderFormula(Forall, x, PredicateFormula(equality, Seq(x, x)))
+    val existsXEq = BinderFormula(Exists, x, PredicateFormula(equality, Seq(x, x)))
+    val existsYEq = BinderFormula(Exists, y, PredicateFormula(equality, Seq(y, y)))
+    assert(
+      Parser.printSequent(Sequent(Set(forallEq), Set(existsYEq, existsXEq))) == "∀ ?x. ?x = ?x ⊢ ∃ ?y. ?y = ?y; " +
+        "∃ ?x. ?x = ?x"
+    )
+    assert(
+      Parser.printSequent(Sequent(Set(forallEq, PredicateFormula(ConstantPredicateLabel("p", 0), Seq())), Set(existsYEq, existsXEq))) == "∀ ?x. ?x = ?x; p ⊢ ∃ ?y. ?y = ?y; ∃ ?x. ?x = ?x"
+    )
+  }
+
+  // warning: this test might be flaky because formula order is not fixed in sequents but fixed in the string representation
+  test("sequents from Mapping and SetTheory") {
+    val va = VariableLabel("a")
+    val leftAndRight = BinderFormula(ExistsOne, x, PredicateFormula(sPhi2, Seq(x, va)))
+    assert(Parser.printSequent(Sequent(Set(leftAndRight), Set(leftAndRight))) == "∃! ?x. ?phi(?x, ?a) ⊢ ∃! ?x. ?phi(?x, ?a)")
+
+    assert(
+      Parser.printSequent(
+        Sequent(
+          Set(BinderFormula(Forall, x, ConnectorFormula(Iff, Seq(x === x1, sPhi1(x))))),
+          Set((z === sf1(x1)) ==> exists(x, (z === sf1(x)) /\ sPhi1(x)))
+        )
+      ) == "∀ ?x. ?x = ?x1 ↔ ?phi(?x) ⊢ ?z = ?f(?x1) ⇒ (∃ ?x. ?z = ?f(?x) ∧ ?phi(?x))"
+    )
+    assert(
+      Parser.printSequent(
+        exists(x1, forall(x, (x === x1) <=> (sPhi1(x)))) |- exists(
+          z1,
+          forall(z, (z === z1) <=> exists(x, (z === sf1(x)) /\ sPhi1(x)))
+        )
+      ) == "∃ ?x1. ∀ ?x. ?x = ?x1 ↔ ?phi(?x) ⊢ ∃ ?z1. ∀ ?z. ?z = ?z1 ↔ (∃ ?x. ?z = ?f(?x) ∧ ?phi(?x))"
+    )
+    assert(Parser.printSequent((() |- (x === x) \/ (x === y))) == "⊢ ?x = ?x ∨ ?x = ?y")
+    assert(
+      Parser.printSequent(
+        Set(
+          (x === x) \/ (x === y),
+          ((x === x) \/ (x === y)) <=> ((x === xPrime) \/ (x === yPrime))
+        ) |- (x === xPrime) \/ (x === yPrime)
+      ) == "?x = ?x ∨ ?x = ?y; ?x = ?x ∨ ?x = ?y ↔ ?x = ?x' ∨ ?x = ?y' ⊢ ?x = ?x' ∨ ?x = ?y'"
+    )
+  }
 }