diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index dbe033a..fb1bfcc 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -8,7 +8,7 @@ jobs:
     runs-on: ubuntu-latest
     strategy:
       matrix:
-        python-version: [3.6, 3.7, 3.8]
+        python-version: [3.6, 3.7, 3.8, 3.9]
 
     steps:
     - uses: actions/checkout@v2
diff --git a/doq/cli.py b/doq/cli.py
index 287e6c5..1d7b7ff 100644
--- a/doq/cli.py
+++ b/doq/cli.py
@@ -226,10 +226,10 @@ def run(args):
 
         if args.write and target['path'] != '<stdin>':
             with open(target['path'], 'w') as f:
-                f.write(output)
+                f.write(output + '\n')
 
         else:
-            sys.stdout.write(output)
+            sys.stdout.write(output + '\n')
 
     return True
 

diff --git a/tests/test_cli.py b/tests/test_cli.py
index 16dffd9..9a3ae16 100644
--- a/tests/test_cli.py
+++ b/tests/test_cli.py
@@ -59,7 +59,7 @@ class CliTestCase(TestCase):
                     run(args)
             actual = p.getvalue().split('\n')
             with open(os.path.join(expected_path, file)) as f:
-                expected = f.read().rstrip().split('\n')
+                expected = f.read().split('\n')
 
             self.assertSequenceEqual(expected, actual)
 
@@ -108,7 +108,7 @@ class CliTestCase(TestCase):
                     run(args)
             actual = p.getvalue().split('\n')
             with open(os.path.join(expected_path, file)) as f:
-                expected = f.read().rstrip().split('\n')
+                expected = f.read().split('\n')
 
             self.assertSequenceEqual(expected, actual)
 
@@ -157,7 +157,7 @@ class CliTestCase(TestCase):
                     run(args)
             actual = p.getvalue().split('\n')
             with open(os.path.join(expected_path, file)) as f:
-                expected = f.read().rstrip().split('\n')
+                expected = f.read().split('\n')
 
             self.assertSequenceEqual(expected, actual)
 

EOF newline is stripped off
Take the following file as an example:
```
# file.py
def f(x):
    pass

```
Notice the last empty line which is *required* by git to diff files properly.

Now, passing this file to doq using this command: `doq -w -f file.py`, produces the following:
```
# file.py
def f(x):
    """f.

    :param x:
    """
    pass
```
Notice that the last line has been stripped
tests/test_cli.py::CliTestCase::test_output_with_google_style tests/test_cli.py::CliTestCase::test_output_with_numpy_style tests/test_cli.py::CliTestCase::test_output_with_sphinx_style
tests/test_cli.py::CliTestCase::test_find_files tests/test_cli.py::CliTestCase::test_get_defalt_template_path_0_sphinx tests/test_cli.py::CliTestCase::test_get_defalt_template_path_1_google tests/test_cli.py::CliTestCase::test_get_defalt_template_path_2_numpy tests/test_cli.py::CliTestCase::test_get_lines tests/test_cli.py::CliTestCase::test_get_target tests/test_cli.py::CliTestCase::test_get_template_path tests/test_cli.py::CliTestCase::test_is_doc_exists tests/test_cli.py::CliTestCase::test_no_files tests/test_cli.py::CliTestCase::test_no_output_with_google_style tests/test_cli.py::CliTestCase::test_no_output_with_numpy_style tests/test_cli.py::CliTestCase::test_no_output_with_sphinx_style tests/test_cli.py::CliTestCase::test_not_ignore_exception tests/test_cli.py::CliTestCase::test_not_ignore_yield tests/test_cli.py::CliTestCase::test_omit_one tests/test_cli.py::CliTestCase::test_omit_two tests/test_cli.py::CliTestCase::test_run_with_classes tests/test_cli.py::CliTestCase::test_run_with_defs