1

I have written some unittests that use Selenium and created a Tkinter GUI for it.

script.py is:

from selenium import webdriver
import unittest

class LaunchChrome(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        cls.driver = webdriver.Chrome(r"C:\Users\USERNAME\PycharmProjects\First\Drivers\chromedriver.exe")
        cls.driver.maximize_window()
        cls.driver.get('https://facebook.com')

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

interface.py is:

from tkinter import Button
from tkinter.ttk import *
import unittest
from ex import LaunchChrome

class HomeApplication:

    def init_page(self):

        self.buStart = Button(self, text="Start", width=60)
        self.buStart.grid(row=4, column=0, columnspan=3)
        self.buStart.config(command=self.start_app)
    def run(self):
        Launch_Chrome = unittest.TestLoader().loadTestsFromTestCase(LaunchChrome)
        test_suite = unittest.TestSuite([Launch_Chrome])
        unittest.TextTestRunner(verbosity=2).run(test_suite)
    def start_app(self):
        print("run")
        self.run()

After I open the GUI and click on the "Start" button, unittests work fine but the GUI stops to respond (Not Responding):

(Not Responding)

How can I use multiprocessing is this code?

Demian Wolf
  • 1,698
  • 2
  • 14
  • 34
john
  • 75
  • 1
  • 8
  • When you run the Selenium script you pause the Tkinter mainloop while the script is executing, and, consequently, the window is not responding. Have you tried to use threading? – Demian Wolf May 31 '20 at 13:47
  • 1
    I add this code threading.Thread(target=self.run()) in function start_app but not same problem – john May 31 '20 at 14:01
  • 1
    what is the best to do it by threading or multiprocessing, I see Python doc recommended to use multiprocessing – john May 31 '20 at 14:03
  • Of course, if you call threading.Thread(target=self.run**()**). This is a very popular mistake. You need to send a function as the target arg, but you send its **execution** result. Try to change the line `threading.Thread(target=self.run())` to `threading.Thread(target=self.run)`. – Demian Wolf May 31 '20 at 14:12
  • Regarding your second question, look here: https://stackoverflow.com/questions/3044580/multiprocessing-vs-threading-python – Demian Wolf May 31 '20 at 14:14
  • 1
    If threading.Thread(target=self.run()) to threading.Thread(target=self.run), the script not launch – john May 31 '20 at 14:22
  • Haven't you forgot about thread.start() and thread.join()? – Demian Wolf May 31 '20 at 14:23
  • 1
    I add it same problem bro – john May 31 '20 at 14:31

1 Answers1

3

The tests are running in the main thread. The Tkinter mainloop waits for the start_app method to return, which does not happen until the tests finish execution.

To solve the problem, you can spawn a separate thread or process specifically for the tests.

For example, replace interface.py with the following:

import unittest
import tkinter as tk
import tkinter.ttk as ttk
from threading import Thread

from ex import LaunchChrome


class HomeApplication(tk.Tk):
    def __init__(self):
        super().__init__()
        
        ttk.Button(self, text="Start", width=60, command=self.start_app)\
                     .grid(row=4, column=0, columnspan=3)

    def run_tests(self):
        test_suite = unittest.TestSuite([unittest.TestLoader()\
                                         .loadTestsFromTestCase(LaunchChrome)])
        unittest.TextTestRunner(verbosity=2).run(test_suite)

    def start_app(self):
        Thread(target=self.run_tests, daemon=True).start()


if __name__ == "__main__":
    HomeApplication().mainloop()
Demian Wolf
  • 1,698
  • 2
  • 14
  • 34
  • 1
    Thanks all fine but what is daemon=True, I add Thread(target=self.run_tests).start() without daemon=True and work fin – john May 31 '20 at 15:06
  • 1
    @john if daemon=True specified, the additional thread is stopped together with the main one. Though in this case it is not much useful because browser and Chrome driver will not be closed even if the Python process will be stopped (not only the thread). – Demian Wolf May 31 '20 at 15:08