3

I am trying to run a python3 unit test script but it gives me a module not found error when it uses objects from the main scipt and comes across import statements. I don't face this error when I run the main script itself and the code run as expected. The error traceback that I get is:

Traceback (most recent call last):
  File "parkingLot_test.py", line 3, in <module>
    from source import parking  
  File "/home/stash/Desktop/parking-lot/parking-lot-1.4.2/parking_lot/parking_lot/bin/source/parking.py", line 1, in <module>
    import lot

ModuleNotFoundError: No module named 'lot'

The directory structure is as follows:

├── file_inputs.txt
├── parking_lot
├── parkingLot_test.py
├── run_functional_tests
├── setup
└── source
    ├── car.py
    ├── __init__.py
    ├── lot.py
    ├── main.py
    ├── parking.py

The code for unit test file parkingLot_test.py:

import unittest
from source import parking  

class ParkingTest(unittest.TestCase):

    @classmethod
    def MakeClass(cls):
        cls.parking = parking.Parking()
        cls.allocated_slot = 1

    def test_a_create_parking_lot(self):
        parking_slots = 6
        self.parking.create_parking_lot(parking_slots)
        self.assertEqual(len(self.parking.slots), parking_slots,
                         msg="Wrong parking lot created")

    def test_b_park(self):
        registration_no = "MH-12-FF-2017"
        colour = "Black"
        self.parking.park(registration_no, colour)
        self.assertFalse(
            self.parking.slots[self.allocated_slot].available, "Park failed.")
        for i in self.parking.slots.values():
            if not i.available and i.car:
                self.assertEqual(i.car.registration_no,
                                 registration_no, "Park failed")
                self.assertEqual(i.car.colour, colour, "Park failed")

    def test_c_leave(self):
        self.parking.leave(self.allocated_slot)
        self.assertTrue(
            self.parking.slots[self.allocated_slot].available, "Leave failed.")

    @classmethod
    def RemoveClass(cls):
        del cls.parking


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

The code for the imported file parking.py:

import lot
import car


class Parking:
    """
    Parking class which has details about parking slots
    as well as operation performed on parking are present here
    """

    def __init__(self):
        self.slots = {}

    def create_parking_lot(self, no_of_slots):
        """This method will create parking lot if not present already with given
        number of slots.
        Input: no_of_slots - Integer Type
        """
        no_of_slots = int(no_of_slots)

        if len(self.slots) > 0:
            print("Parking Lot already created")
            return

        if no_of_slots > 0:
            for i in range(1, no_of_slots+1):
                temp_slot = lot.ParkingSlot(slotNum=i,
                                            availability=True)

                self.slots[i] = temp_slot
            print("Created a parking lot with %s slots" % no_of_slots)
        else:
            print("Number of slots provided is incorrect.")
        return

    def get_nearest_available_slot(self):
  ...................

How can I fix this issue?

  • The folder `source` needs to be added to the import path by either appending it's path to `sys.path` or by putting it in `PYTHONPATH` – rdas Jun 11 '19 at 05:01
  • @rdas I still get the `ModuleNotFoundError: No module named 'lot'` –  Jun 11 '19 at 05:51
  • I used `sys.path.append("./")` before the import lot statement and tried running parking.py directly @rdas. –  Jun 11 '19 at 06:01

2 Answers2

6

As python 3 doesn't support Implicit relative import. You can use explicit relative import.

Try using the following line instead of import lot in parking.py

from . import lot

Vishal
  • 96
  • 3
  • 1
    Try running the script using this command `python -m parkingLot_test` – Vishal Jun 11 '19 at 06:26
  • 1
    I get an error `ImportError: attempted relative import with no known parent package` with you method on the main script and on using `python -m parkingLot_test` the test script seems to be running fine except for some python3 syntax difference errors. So, it seems to be running as expected for Python 2.7 –  Jun 11 '19 at 06:28
  • 1
    Information about `__package__` [here](https://docs.python.org/3/reference/import.html#__package__) When running a script directly, it doesn't set the `__package__` attribute and so it is set to none. If you run the script using **-m** flag, it tells the interpreter to treat file as a module. – Vishal Jun 11 '19 at 06:50
2

in the same directory level file when you import the one file in another use relative import like

in parking.py file importing lot.py file as

import .log

and when import from one directory to lower directory ie importing lot in parkingLot_test.py, use from source import lot

and in the source folder in __init__.py file write

import .lot
import .parking

like this.

sahasrara62
  • 10,069
  • 3
  • 29
  • 44