I have a simple file program (removed code from functions since its irrelevant for the problem):
import random
import sys
def poziom(level):
*does something and returns something*
def gra(chance):
*does something and returns something*
def save(name):
*does something and returns something*
while True:
*does something in loop, executing other functions above*
I'm trying to run a simple unit test against one of its functions:
import unittest
from my_game import save
from my_game import gra
from my_game import poziom
class TestSum(unittest.TestCase):
def test_list_int(self):
"""
Test that it can sum a list of integers
"""
check = "Test string"
result = poziom(check)
self.assertEqual(result, 0)
if __name__ == '__main__':
unittest.main()
However, this test instead of running a poziom() function, runs through entire file, also executing the code behind the While True statement.
Do I do something wrong? Is it possible in such case to write a test that checks ONLY one function and value returned by it?
However, this test instead of running a poziom() function, runs through entire file, also executing the code behind the While True statement. Do I do something wrong?
This is how import works. It executes the code in the file that you import. To solve the problem put the while loop in a if __name__ == '__main__': just like you do in your test file.
Related
I'm already struggeling some hours with a problem within my python project.
The situation is as follows:
I have a script A.py and a Script B.py
**Script A.py:**
#in this script the function def main() is running
def main():
#some coding in here
x=str(body)#then i assign the string of the variable body to a new variable x
#some other coding in here
if __name__=='__main__':
main()
REMIND: this a pseudo code to explain my struggle (the script as a standalone module is working properly) !
Now I have Script B.py (in the same folder)
**Script B.py** #in this script i try to run Script A.py and assign the value of variable x to a new variable in order to do furhter processing with it.
import A
A.main() # When importing the module and excuting its main() function by running B.py I see the values of variable x appearing on my screen
QUESTION: How can I assign the value of variable x now to a new variable so that i can do further processing with it in B.py ? Is this even possible ?
Cause after calling the main function of A.py no other operations are processed.
Please consider that I'm a relatively newby regaring programming over several modules.
I would be very glad for any help.
Thank you very much in advance
Kind regards
Slin
Ok i tried your approaches but still not getting the desired result.
A.py is a AMQP subscribing script (https://www.rabbitmq.com/tutorials/tutorial-one-python.html) (see below):
import pika
credentials = pika.PlainCredentials('admin', 'admin')
connection = pika.BlockingConnection(pika.ConnectionParameters('Ipaddress',
5672,
'/',
credentials))
#connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
channel = connection.channel()
channel.exchange_declare(exchange='logs',
exchange_type='fanout')
result = channel.queue_declare(exclusive=True)
queue_name = result.method.queue
channel.queue_bind(exchange='logs',
queue=queue_name)
print(' [*] Waiting for logs. To exit press CTRL+C')
def callback(ch, method, properties, body):
x = str(body)
print str(x)
channel.basic_consume(callback,
queue=queue_name,
no_ack=True)
channel.start_consuming()
if __name__ == '__main__':
main()
B.py:
import pika
import A
A.main()
With the approaches so far i get the same as shown with the coding above.
I would like to assign x (which values can chane when A is running) to a new variable within B.py to do some processing to publish it afterwards with the counterpart script of A.py.
When executing B.py i receive:
[*] Waiting for logs. To exit press CTRL+C
['20'] #this is the string of variable x from script A
Now i want to assign this ['20'] to a new variable wihtin B.py.. but the script B.py keeps running A.main() (which is logical cause it is a loop).
Thanks so far for your support.
Kind regards
You could return the value of x to script B using the return statement:
return str(body)#then i assign the string of the variable body to a new variable x
Then get this value in script B by storing it in a variable x = A.main().
Make x as a global variable inside A.py
**Script A.py:**
#in this script the function def main() is running
x = ''
def main():
global x
#some coding in here
x=str(body)
#then i assign the string of the variable body to a new variable x
if __name__=='__main__':
main()
Now you can access that x from B.py as A.x
Just treat it like you do with any other module. In script A, create a function as you have called main. In it you have to have a variable that you can insert from the other script, call it body.
Script A:
def main(body):
...
return x
Next you import the other script like you would any other model, using import _.py as _. The you use the function as you would in the other script, B. It is as if you are importing an object A and calling its method b.
Script B:
import a.py as A
object = A.main(thing2string) # or object = A.main() if the script b has something to return
Now you have the object that is created in A from that you can process in be. For example,
processed = [object[i] for i in object]
# ... processing steps
I don't know if you can have it notify you on change. But you use a timer to check if the value is updated and use an if statement to update if it has.
Summary:
You have to add the return line in script A. And you have to set a variable equal to it in script b. This new variable then becomes whatever b returns.
I have the following structure in code.
In main.py:
def run(parameters):
# do something
In execution.py:
import main
if __name__ = "main":
main.run(parameters)
However, I get the following error - main has no 'run' member.
When I run that code there is no output, because the test in execution.py should be if __name__ == "__main__":. The if-test in your code is never true.
Buy when I fix that problem, main.run() executes as expected, but only if I fix another problem. The function body of run() must consist of more than a comment. You need pass at the very least.
So that is a syntax error, which means that the def statement doesn't actually define the function. Which explains the message.
I am doing a simple project on my Pycharm IDE.
My code is this:
import webbrowser
import time
socialMediaUrls = ["www.google.com","www.edureka.com"]
techUrls = ["www.udacity.com","www.dailymotion.com"]
def open_tabs(url_list):
for element in url_list:
webbrowser.open_new_tab(element)
def main():
webbrowser.open("www.youtube.com",new=0,autoraise=false)
time.sleep(1)
open.tab(socialMedialUrls)
open_tabs(techUrls)
main()
but after running I am getting this message:
C:\Users\adc\AppData\Local\Programs\Python\Python36-32\python.exe
C:/Users/adc/PycharmProjects/untitled1/ur.py
Process finished with exit code 0
And I am getting same message for all my projects. What should I do?
You should call main in that way:
def main():
webbrowser.open("www.youtube.com",new=0,autoraise=false)
time.sleep(1)
open.tab(socialMedialUrls)
open_tabs(techUrls)
if __name__ == "__main__":
main()
Also I see that your code contains some other errors. For example, in Python there is False keyword, not false. Lines with open.tab and open_tabs will not work too.
Currently, no instructions are reachable in your script (besides the import statements)
in:
def main():
webbrowser.open("www.youtube.com",new=0,autoraise=false)
time.sleep(1)
open.tab(socialMedialUrls)
open_tabs(techUrls)
main()
indentation suggests that you're performing a recursive call (which isn't what you want).
Unindent main() to make sure you execute something in your script.
Or put the instructions of main at zero-indent level outside any procedure (in that case, it is executed even when importing the module, probably not important here)
(note that python programs don't need a main(), this isn't C)
I have a Python script that accepts one input (a text file): ./myprog.py file.txt. The script outputs a string based on the given input.
I have a set of test files that I would like to test my program with. I know the expected output for each file and want to make sure my script produces the correct output for each file.
What is the generally accepted way to do this type of testing?
I was thinking of using Python's unittest module as the testing framework, and then running my script through subprocess.check_output(stderr=subprocess.STDOUT), capturing stdout and stderr, and then doing a unittest assertEqual to compare the actual and expected strings. I want to make sure I'm not missing some nicer solution.
There's two problems here. Testing a program, as opposed to a library of functions, and testing something that prints, as opposed to values returned from a function. Both make testing more difficult, so it's best to side step these problems as much as possible.
The usual technique is to create a library of functions and then have your program be a thin wrapper around that. These functions return their results, and only the program does the printing. This means you can use normal unit testing techniques for most of the code.
You can have a single file which is both a library and a program. Here's a simple example as hello.py.
def hello(greeting, place):
return greeting + ", " + place + "!"
def main():
print(hello("Hello", "World"))
if __name__ == '__main__':
main()
That last bit is how a file can tell if it was run as a program or if it was imported as a library. It allows access to the individual functions with import hello, and it also allows the file to run as a program. See this answer for more information.
Then you can write a mostly normal unit test.
import hello
import unittest
import sys
from StringIO import StringIO
import subprocess
class TestHello(unittest.TestCase):
def test_hello(self):
self.assertEqual(
hello.hello("foo", "bar"),
"foo, bar!"
)
def test_main(self):
saved_stdout = sys.stdout
try:
out = StringIO()
sys.stdout = out
hello.main()
output = out.getvalue()
self.assertEqual(output, "Hello, World!\n")
finally:
sys.stdout = saved_stdout
def test_as_program(self):
self.assertEqual(
subprocess.check_output(["python", "hello.py"]),
"Hello, World!\n"
)
if __name__ == '__main__':
unittest.main()
Here test_hello is unit testing hello directly as a function; and in a more complicated program there would be more functions to test. We also have test_main to unit test main using StringIO to capture its output. Finally, we ensure the program will run as a program with test_as_program.
The important thing is to test as much of the functionality as functions returning data, and to test as little as possible as printed and formatted strings, and almost nothing via running the program itself. By the time we're actually testing the program, all we need to do is check that it calls main.
So in my file1.py, I have something like:
def run():
# Do something
print "Hi"
Now I want to use function run() in another file.
from file1.py import run
However, when I execute the other file it also prints Hi. How do I suppress this?
Add the print "Hi" in an if __name__ == "__main__" clause.
When python imports modules it executes the code contained in them in order to build the module namespace. If you run the module as the main script the __name__ is going to get assigned to __main__ and the code inside the if clause is going to get executed.
Since you're not running the script as the main script the __name__ gets assigned to the modules __name__ (in this case file1) and as a result this test will not succeed and the print statement is not going to get executed.
def run():
# Do something
if __name__ == "__main__":
print "Hi"
You should include after the functions this:
this runs the program
if main == "name":# before and after 'main' and 'name' there are two under_scores!
print "hi" etc...
if you don't want Hi to be printed, simply delete from your file1.py
if you want Hi to be printed when run() is called, then indent it so that it belongs to the run() function.