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.

1 Answer 1

0

Inside the testCalc.py file, add the following.

import sys
import os

sys.path.append(os.path.abspath('../calculatorAlgo'))
from calculator import simpleCalc
Sign up to request clarification or add additional context in comments.

2 Comments

I've added a forward slash that was missing.
Messing with the path seems hacky to me.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.