2

Question on unit testing

Goal: The goal is to use pyUnit in testCalc.py to unit test the simpleCalc object in calculator.py.
Problem: I cannot successfully import the simpleCalc object from calculator.py into testCalc.py when testCalc is run from a separate directory in the project.
Background: The unit test in testCalc.py runs perfectly fine when it's included in the same directory as calculator.py, but when I move it into a separate folder and try to import the simpleCalc object defined in calculator.py, I get an error. I am trying to learn how to use the pyUnit unit testing framework in a simple project and I'm clearly missing something basic about how to import modules for unit testing in a hierarchical directory structure. The basic calculator_test project described below is a simple project that I created to practice. You can see all the posts I've gone through already at the end of this post.
Ultimate Question: How can I import the simpleCalc object into testCalc.py with the directory hierarchy described below?

Github: https://github.com/jaybird4522/calculator_test/tree/unit_test

Here's my directory structure:

calculator_test/
    calculatorAlgo/
        __init__.py
        calculator.py
    test_calculatorAlgo/
        __init__.py
        testCalc.py
        testlib/
            __init__.py
            testcase.py

Here's the calculator.py file, which describes the simpleCalc object I want to unit test:

# calculator.py

class simpleCalc(object):

    def __init__(self):
        self.input1 = 0
        self.input2 = 0

    def set(self, in1, in2):
        self.input1 = in1
        self.input2 = in2

    def subtract(self, in1, in2):
        self.set(in1, in2)
        result = self.input1 - self.input2
        return result

Here's the testCalc.py file, which contains the unit tests:

# testCalc.py

import unittest
from calculatorAlgo.calculator import simpleCalc

class testCalc(unittest.TestCase):

    # set up the tests by instantiating a simpleCalc object as calc
    def setUp(self):
        self.calc = simpleCalc()

    def runTest(self):
        self.assertEqual(self.calc.subtract(7,3),4)

if __name__ == '__main__':
    unittest.main()

I have been running the unit test file with the simple command:

testCalc.py

What I've attempted so far

First Attempt
I tried simply importing the simpleCalc object based on where it's located in the directory structure:

# testCalc.py

import unittest
from .calculatorAlgo.calculator import simpleCalc

class testCalc(unittest....

And got this error:
ValueError: Attempted relative import in non-package

Second Attempt
I tried importing it without relative references:

# testCalc.py

import unittest
import simpleCalc

class testCalc(unittest....

And got this error:
ImportError: No module named simpleCalc

Third Attempt
Based on this post, http://blog.aaronboman.com/programming/testing/2016/02/11/how-to-write-tests-in-python-project-structure/, I tried creating a separate base class called testcase.py which could do the relative imports.

# testcase.py

from unittest import TestCase
from ...calculator import simpleCalc

class BaseTestCase(TestCase):
    pass

And changed my imports in testCalc.py

# testCalc.py

import unittest
from testlib.testcase import BaseTestCase

class testCalc(unittest....

And got this error:
ValueError: Attempted relative import beyond toplevel package

Other Resources
Here are some of the posts I've worked through to no avail:
Import a module from a relative path
python packaging for relative imports
How to fix "Attempted relative import in non-package" even with __init__.py
Python importing works from one folder but not another
Relative imports for the billionth time

Ultimately, I feel that I'm just missing something basic, even after a lot of research. This feels like a common setup, and I'm hoping someone can tell me what I'm doing wrong, and that it might help others avoid this problem in the future.

Community
  • 1
  • 1
jaybird4522
  • 21
  • 1
  • 2

1 Answers1

0

Inside the testCalc.py file, add the following.

import sys
import os

sys.path.append(os.path.abspath('../calculatorAlgo'))
from calculator import simpleCalc
Benjamin Rowell
  • 1,371
  • 8
  • 16