-1

I have developed a Tkinter application which will basically display the test functions inside a test file and the user can select the particular test functions and run pytest on it. It was working well so far as I had only test functions and no classes. Now, there are classes and functions inside it. How do I capture that those functions come inside that particular class? I thought of using regex but there might be functions outside the class too. So, I dont know how to solve this issue.

So far I have something like this:

Test file:

def test_x():
   ....
def test_y():
   ....

Source Code:

with open("{}.py".format(testFile), "r") as fp:
    line = fp.readline()
    while line:
        line = fp.readline()
        if ("#" not in line) and ("def" and "test_" in line):
            x = line.split()[1].split('(')[0]
            gFunctionList.append([testName, x])

Based on which all selected:

#var2State is the checkbutton states
for j in range(len(var2State)):
    if var2State[j].get() == 1:
        runString += "{}.py::{} ".format(gFunctionList[j][0],
                                         gFunctionList[j][1])
    else:
        continue
    if runString != "":
        res = os.system("pytest " + runString)

From the above code, it will run: pytest testFile.py::test_x if test_x is selected.

Now if the test file is like this:

Class test_Abc():
    def test_x():
       ....
    def test_y():
       ....

def test_j():
   ....

Class test_Xyz():
   def k():
      ....
   def test_l():
      ....

Class test_Rst():
   def test_k():
      ....
   def ltest_():
      ....

Now, if test_l is selected, it should run: pytest testFile.py::test_Xyz::test_l.

But how do I get the test_Xyz above?

if test_j is selected, it should run: pytest testFile.py::test_j.

So, how do I capture the class name right outside a particular set of test functions and not capture if it's not inside the class?

HoldOffHunger
  • 18,769
  • 10
  • 104
  • 133
chan
  • 47
  • 11
  • https://stackoverflow.com/questions/1690400/getting-an-instance-name-inside-class-init – dubbbdan Jul 30 '19 at 18:39
  • @dubbbdan, I didn't quite get what it explains. My question is how do I get the class name when a particular test function is selected? And no class is taken when just a function without a class is selected. – chan Jul 30 '19 at 21:16
  • 1
    Your naive attempt at parsing python code won't get you too far. But why bother at all? The python interpreter already knows how to do it and [exposes](https://docs.python.org/3/library/ast.html#ast.parse) that functionality in the standard library. – Stop harming Monica Jul 30 '19 at 22:15
  • 2
    Even the AST parsing won't bring you far when it comes to parametrized or dynamically generated tests; you need to run `pytest.main(args='--collect-only', '--quiet')`, capture and parse the output. – hoefling Jul 31 '19 at 05:06

1 Answers1

1

I am not really that familiar with Tkinter or how things get selected, but this might point you in the right direction.

As the link I provided in the comments indicates, instances (i.e. classes) do not have names. If you want to give an instance a name, you just need to include it in the def __init__(self):. When any method (i.e. function) from test_ABC (which also inherits self) is called, you will always have access to self.name.

class test_Abc():
    def __init__(self):
        self.name = 'test_Abc'
    def test_x(self):
       return self.name
    def test_y(self):
       return self.name

abc = test_Abc()

a = abc.test_x()

print('pytest testFile.py::' + a + '::test_x')

which returns:

pytest testFile.py::test_Abc::test_x
dubbbdan
  • 2,650
  • 1
  • 25
  • 43