diff --git a/Lib/test/test_turtle.py b/Lib/test/test_turtle.py
new file mode 100644
index 0000000..70620d5
--- /dev/null
+++ b/Lib/test/test_turtle.py
@@ -0,0 +1,400 @@
+import unittest
+from test import test_support as support
+
+turtle = support.import_module('turtle')
+Vec2D = turtle.Vec2D
+
+test_config = """\
+width = 0.75
+height = 0.8
+canvwidth = 500
+canvheight = 200
+leftright = 100
+topbottom = 100
+mode = world
+colormode = 255
+delay = 100
+undobuffersize = 10000
+shape = circle
+pencolor  = red
+fillcolor  = blue
+resizemode  = auto
+visible  = None
+language = english
+exampleturtle = turtle
+examplescreen = screen
+title = Python Turtle Graphics
+using_IDLE = ''
+"""
+
+test_config_two = """\
+# Comments!
+# Testing comments!
+pencolor  = red
+fillcolor  = blue
+visible  = False
+language = english
+# Some more
+# comments
+using_IDLE = False
+"""
+
+invalid_test_config = """
+pencolor = red
+fillcolor: blue
+visible = False
+"""
+
+
+class TurtleConfigTest(unittest.TestCase):
+
+    def get_cfg_file(self, cfg_str):
+        self.addCleanup(support.unlink, support.TESTFN)
+        with open(support.TESTFN, 'w') as f:
+            f.write(cfg_str)
+        return support.TESTFN
+
+    def test_config_dict(self):
+
+        cfg_name = self.get_cfg_file(test_config)
+        parsed_cfg = turtle.config_dict(cfg_name)
+
+        expected = {
+            'width' : 0.75,
+            'height' : 0.8,
+            'canvwidth' : 500,
+            'canvheight': 200,
+            'leftright': 100,
+            'topbottom': 100,
+            'mode': 'world',
+            'colormode': 255,
+            'delay': 100,
+            'undobuffersize': 10000,
+            'shape': 'circle',
+            'pencolor' : 'red',
+            'fillcolor' : 'blue',
+            'resizemode' : 'auto',
+            'visible' : None,
+            'language': 'english',
+            'exampleturtle': 'turtle',
+            'examplescreen': 'screen',
+            'title': 'Python Turtle Graphics',
+            'using_IDLE': '',
+        }
+
+        self.assertEqual(parsed_cfg, expected)
+
+    def test_partial_config_dict_with_commments(self):
+
+        cfg_name = self.get_cfg_file(test_config_two)
+        parsed_cfg = turtle.config_dict(cfg_name)
+
+        expected = {
+            'pencolor': 'red',
+            'fillcolor': 'blue',
+            'visible': False,
+            'language': 'english',
+            'using_IDLE': False,
+        }
+
+        self.assertEqual(parsed_cfg, expected)
+
+    def test_config_dict_invalid(self):
+
+        cfg_name = self.get_cfg_file(invalid_test_config)
+
+        with support.captured_stdout() as stdout:
+            parsed_cfg = turtle.config_dict(cfg_name)
+
+        err_msg = stdout.getvalue()
+
+        self.assertIn('Bad line in config-file ', err_msg)
+        self.assertIn('fillcolor: blue', err_msg)
+
+        self.assertEqual(parsed_cfg, {
+            'pencolor': 'red',
+            'visible': False,
+        })
+
+
+class VectorComparisonMixin:
+
+    def assertVectorsAlmostEqual(self, vec1, vec2):
+        if len(vec1) != len(vec2):
+            self.fail("Tuples are not of equal size")
+        for idx, (i, j) in enumerate(zip(vec1, vec2)):
+            self.assertAlmostEqual(
+                i, j, msg='values at index {} do not match'.format(idx))
+
+
+class TestVec2D(VectorComparisonMixin, unittest.TestCase):
+
+    def _assert_arithmetic_cases(self, test_cases, lambda_operator):
+        for test_case in test_cases:
+            ((first, second), expected) = test_case
+
+            op1 = Vec2D(*first)
+            op2 = Vec2D(*second)
+
+            result = lambda_operator(op1, op2)
+
+            expected = Vec2D(*expected)
+
+            self.assertVectorsAlmostEqual(result, expected)
+
+    def test_vector_addition(self):
+
+        test_cases = [
+            (((0, 0), (1, 1)), (1.0, 1.0)),
+            (((-1, 0), (2, 2)), (1, 2)),
+            (((1.5, 0), (1, 1)), (2.5, 1)),
+        ]
+
+        self._assert_arithmetic_cases(test_cases, lambda x, y: x + y)
+
+    def test_vector_subtraction(self):
+
+        test_cases = [
+            (((0, 0), (1, 1)), (-1, -1)),
+            (((10.625, 0.125), (10, 0)), (0.625, 0.125)),
+        ]
+
+        self._assert_arithmetic_cases(test_cases, lambda x, y: x - y)
+
+    def test_vector_multiply(self):
+
+        vec1 = Vec2D(10, 10)
+        vec2 = Vec2D(0.5, 3)
+        answer = vec1 * vec2
+        expected = 35
+        self.assertAlmostEqual(answer, expected)
+
+        vec = Vec2D(0.5, 3)
+        answer = vec * 10
+        expected = Vec2D(5, 30)
+        self.assertVectorsAlmostEqual(answer, expected)
+
+    def test_vector_negative(self):
+        vec = Vec2D(10, -10)
+        expected = (-10, 10)
+        self.assertVectorsAlmostEqual(-vec, expected)
+
+    def test_distance(self):
+        vec = Vec2D(6, 8)
+        expected = 10
+        self.assertEqual(abs(vec), expected)
+
+        vec = Vec2D(0, 0)
+        expected = 0
+        self.assertEqual(abs(vec), expected)
+
+        vec = Vec2D(2.5, 6)
+        expected = 6.5
+        self.assertEqual(abs(vec), expected)
+
+    def test_rotate(self):
+
+        cases = [
+            (((0, 0), 0), (0, 0)),
+            (((0, 1), 90), (-1, 0)),
+            (((0, 1), -90), (1, 0)),
+            (((1, 0), 180), (-1, 0)),
+            (((1, 0), 360), (1, 0)),
+        ]
+
+        for case in cases:
+            (vec, rot), expected = case
+            vec = Vec2D(*vec)
+            got = vec.rotate(rot)
+            self.assertVectorsAlmostEqual(got, expected)
+
+
+class TestTNavigator(VectorComparisonMixin, unittest.TestCase):
+
+    def setUp(self):
+        self.nav = turtle.TNavigator()
+
+    def test_goto(self):
+        self.nav.goto(100, -100)
+        self.assertAlmostEqual(self.nav.xcor(), 100)
+        self.assertAlmostEqual(self.nav.ycor(), -100)
+
+    def test_pos(self):
+        self.assertEqual(self.nav.pos(), self.nav._position)
+        self.nav.goto(100, -100)
+        self.assertEqual(self.nav.pos(), self.nav._position)
+
+    def test_left(self):
+        self.assertEqual(self.nav._orient, (1.0, 0))
+        self.nav.left(90)
+        self.assertVectorsAlmostEqual(self.nav._orient, (0.0, 1.0))
+
+    def test_right(self):
+        self.assertEqual(self.nav._orient, (1.0, 0))
+        self.nav.right(90)
+        self.assertVectorsAlmostEqual(self.nav._orient, (0, -1.0))
+
+    def test_reset(self):
+        self.nav.goto(100, -100)
+        self.assertAlmostEqual(self.nav.xcor(), 100)
+        self.assertAlmostEqual(self.nav.ycor(), -100)
+        self.nav.reset()
+        self.assertAlmostEqual(self.nav.xcor(), 0)
+        self.assertAlmostEqual(self.nav.ycor(), 0)
+
+    def test_forward(self):
+        self.nav.forward(150)
+        expected = Vec2D(150, 0)
+        self.assertVectorsAlmostEqual(self.nav.position(), expected)
+
+        self.nav.reset()
+        self.nav.left(90)
+        self.nav.forward(150)
+        expected = Vec2D(0, 150)
+        self.assertVectorsAlmostEqual(self.nav.position(), expected)
+
+        self.assertRaises(TypeError, self.nav.forward, 'skldjfldsk')
+
+    def test_backwards(self):
+        self.nav.back(200)
+        expected = Vec2D(-200, 0)
+        self.assertVectorsAlmostEqual(self.nav.position(), expected)
+
+        self.nav.reset()
+        self.nav.right(90)
+        self.nav.back(200)
+        expected = Vec2D(0, 200)
+        self.assertVectorsAlmostEqual(self.nav.position(), expected)
+
+    def test_distance(self):
+        self.nav.forward(100)
+        expected = 100
+        self.assertAlmostEqual(self.nav.distance(Vec2D(0,0)), expected)
+
+    def test_radians_and_degrees(self):
+        self.nav.left(90)
+        self.assertAlmostEqual(self.nav.heading(), 90)
+        self.nav.radians()
+        self.assertAlmostEqual(self.nav.heading(), 1.57079633)
+        self.nav.degrees()
+        self.assertAlmostEqual(self.nav.heading(), 90)
+
+    def test_towards(self):
+
+        coordinates = [
+            # coordinates, expected
+            ((100, 0), 0.0),
+            ((100, 100), 45.0),
+            ((0, 100), 90.0),
+            ((-100, 100), 135.0),
+            ((-100, 0), 180.0),
+            ((-100, -100), 225.0),
+            ((0, -100), 270.0),
+            ((100, -100), 315.0),
+        ]
+
+        for (x, y), expected in coordinates:
+            self.assertEqual(self.nav.towards(x, y), expected)
+            self.assertEqual(self.nav.towards((x, y)), expected)
+            self.assertEqual(self.nav.towards(Vec2D(x, y)), expected)
+
+    def test_heading(self):
+
+        self.nav.left(90)
+        self.assertAlmostEqual(self.nav.heading(), 90)
+        self.nav.left(45)
+        self.assertAlmostEqual(self.nav.heading(), 135)
+        self.nav.right(1.6)
+        self.assertAlmostEqual(self.nav.heading(), 133.4)
+        self.assertRaises(TypeError, self.nav.right, 'sdkfjdsf')
+        self.nav.reset()
+
+        rotations = [10, 20, 170, 300]
+        result = sum(rotations) % 360
+        for num in rotations:
+            self.nav.left(num)
+        self.assertEqual(self.nav.heading(), result)
+        self.nav.reset()
+
+        result = (360-sum(rotations)) % 360
+        for num in rotations:
+            self.nav.right(num)
+        self.assertEqual(self.nav.heading(), result)
+        self.nav.reset()
+
+        rotations = [10, 20, -170, 300, -210, 34.3, -50.2, -10, -29.98, 500]
+        sum_so_far = 0
+        for num in rotations:
+            if num < 0:
+                self.nav.right(abs(num))
+            else:
+                self.nav.left(num)
+            sum_so_far += num
+            self.assertAlmostEqual(self.nav.heading(), sum_so_far % 360)
+
+    def test_setheading(self):
+        self.nav.setheading(102.32)
+        self.assertAlmostEqual(self.nav.heading(), 102.32)
+        self.nav.setheading(-123.23)
+        self.assertAlmostEqual(self.nav.heading(), (-123.23) % 360)
+        self.nav.setheading(-1000.34)
+        self.assertAlmostEqual(self.nav.heading(), (-1000.34) % 360)
+        self.nav.setheading(300000)
+        self.assertAlmostEqual(self.nav.heading(), 300000%360)
+
+    def test_positions(self):
+        self.nav.forward(100)
+        self.nav.left(90)
+        self.nav.forward(-200)
+        self.assertVectorsAlmostEqual(self.nav.pos(), (100.0, -200.0))
+
+    def test_setx_and_sety(self):
+        self.nav.setx(-1023.2334)
+        self.nav.sety(193323.234)
+        self.assertVectorsAlmostEqual(self.nav.pos(), (-1023.2334, 193323.234))
+
+    def test_home(self):
+        self.nav.left(30)
+        self.nav.forward(-100000)
+        self.nav.home()
+        self.assertVectorsAlmostEqual(self.nav.pos(), (0,0))
+        self.assertAlmostEqual(self.nav.heading(), 0)
+
+    def test_distance_method(self):
+        self.assertAlmostEqual(self.nav.distance(30, 40), 50)
+        vec = Vec2D(0.22, .001)
+        self.assertAlmostEqual(self.nav.distance(vec), 0.22000227271553355)
+        another_turtle = turtle.TNavigator()
+        another_turtle.left(90)
+        another_turtle.forward(10000)
+        self.assertAlmostEqual(self.nav.distance(another_turtle), 10000)
+
+
+class TestTPen(unittest.TestCase):
+
+    def test_pendown_and_penup(self):
+
+        tpen = turtle.TPen()
+
+        self.assertTrue(tpen.isdown())
+        tpen.penup()
+        self.assertFalse(tpen.isdown())
+        tpen.pendown()
+        self.assertTrue(tpen.isdown())
+
+    def test_showturtle_hideturtle_and_isvisible(self):
+
+        tpen = turtle.TPen()
+
+        self.assertTrue(tpen.isvisible())
+        tpen.hideturtle()
+        self.assertFalse(tpen.isvisible())
+        tpen.showturtle()
+        self.assertTrue(tpen.isvisible())
+
+
+def test_main():
+    support.run_unittest(TurtleConfigTest, TestVec2D, TestTNavigator, TestTPen)
+
+if __name__ == '__main__':
+    test_main()
diff --git a/Misc/NEWS b/Misc/NEWS
index 80c6400..af9cb6f 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -296,6 +296,9 @@
 Tests
 -----
 
+- Issue #21916: Added tests for the turtle module.  Patch by ingrid,
+  Gregory Loyse and Jelle Zijlstra.
+
 - Issue #25940: Changed test_ssl to use self-signed.pythontest.net.  This
   avoids relying on svn.python.org, which recently changed root certificate.
 
