First of all let me tell you that I am new to Sikuli. I have developed some scripts using the Sikuli IDE and it works fine.
But when i created class and have added the tests as methods to it..it does not work. Can someone let me know what am I missing here. my sikuli script is like this:
class Test:
def setUp(self):
openApp("abc")
wait(10)
def tearDown(self):
closeApp("abc")
def test1(self):
click("1401168929740.png")
time.sleep(1)
type('o')
time.sleep(3)
click("1401169004890.png")
wait("1401169047733.png")
type("some text here")
time.sleep(2)
click("1401169154910.png")
time.sleep(10)
print("the outcome")
def test2(self):
wait("1401169193096.png")
click("1401100914478.png")
time.sleep(3)
print("the outcome")
def test3(self):
type("m", KEY_ALT)
type("cus1")
type(Key.ENTER)
time.sleep(2)
type(Key.TAB)
time.sleep(2)
type("10.00")
time.sleep(2)
type(Key.TAB)
time.sleep(2)
type(Key.TAB)
time.sleep(2)
type(Key.ENTER)
time.sleep(3)
type(Key.ENTER)
time.sleep(17)
type(Key.ENTER)
time.sleep(10)
def test4(self):
if exists("1401100952048.png"):
popup("the outcome")
else:
popup("failure message")
I'm no expert, but I'm not sure if a class is what you really want...I question if you really do want a class, because it doesn't look like you're meaning for your Test class to have different attributes, just different pieces of code that will execute.
If you're wanting to wrap up these definitions into one easy-to-call piece of code, you could do it like this--
After defining all of the functions you have listed above, you could define one more function that includes them all:
def setUp():
openApp("abc")
wait(10)
def tearDown():
closeApp("abc")
def test1():
click("1401168929740.png")
time.sleep(1)
type('o')
time.sleep(3)
click("1401169004890.png")
wait("1401169047733.png")
type("some text here")
time.sleep(2)
click("1401169154910.png")
time.sleep(10)
print("the outcome")
def test2():
wait("1401169193096.png")
click("1401100914478.png")
time.sleep(3)
print("the outcome")
def test3():
type("m", KEY_ALT)
type("cus1")
type(Key.ENTER)
time.sleep(2)
type(Key.TAB)
time.sleep(2)
type("10.00")
time.sleep(2)
type(Key.TAB)
time.sleep(2)
type(Key.TAB)
time.sleep(2)
type(Key.ENTER)
time.sleep(3)
type(Key.ENTER)
time.sleep(17)
type(Key.ENTER)
time.sleep(10)
def test4():
if exists("1401100952048.png"):
popup("the outcome")
else:
popup("failure message")
def completeTest():
setUp()
tearDown()
test1()
test2()
test3()
test4()
###program begins here
completeTest()
If you really did want a class, seeing how you're implementing the class could help us see where the problem is. If you want to keep these methods inside the class, then I think the proper way to call them is:
Test.setUp()
Test.tearDown()
Test.test1()
Test.test2()
Test.test3()
Test.test4()
There is a good discussion about how to construct classes in python here (particularly the second answer).
You need to call the class to make it execute.
Also the definitions you made need to be called before they execute.
If you make a definition named __init__, that one will execute when the class is called.
class Test():
def __init__(self):
self.setUp()
self.tearDown()
def setUp(self):
print('Hello')
def tearDown(self):
print('World')
# Run class
Test()
Related
Everything seems to be perfect but on Kivy screen, nothing appears, just black screen! I've tried to rearrange the positions of imports and even installed the pygame but still the problem keeps persisting!
import kivy
from kivy.uix.label import Label
from kivy.uix.gridlayout import GridLayout
from kivy.uix.textinput import TextInput
from kivy.app import App
class MyGrid(GridLayout):
def __init___(self, **kwargs):
super(MyGrid, self).__init__(**kwargs)
self.cols = 2
self.add_widget(Label(text="Name: "))
self.name = TextInput(multiline=False)
self.add_widget(self.name)
self.add_widget(Label(text="Last Name: "))
self.lastname = TextInput(multiline=False)
self.add_widget(self.lastname)
self.add_widget(Label(text="Email: "))
self.email = TextInput(multiline=False)
self.add_widget(self.email)
class MyApp(App):
def build(self):
return MyGrid()
if __name__ == "__main__":
MyApp().run()
There is an extra underscore on line def __init___(self, **kwargs): after init word. Please remove that and then it should run ok.
I'm kinda new to asyncio and async def/await syntax, so I wanted to ask how exactly should I do something like this:
import asyncio
import pygame
import logging
from pygame import *
log = logging.getLogger('')
class Client:
def __init__(self, host, port):
self.host = host
self.port = port
self.loop = asyncio.get_event_loop()
self.loop.run_until_complete(self.create_client())
async def create_client(self):
self.reader, self.writer = await asyncio.open_connection(self.host,
self.port,
loop=self.loop)
asyncio.ensure_future(self._handle_packets(), loop=self.loop)
async def _handle_packets(self):
while True:
data = await self.reader.read(4096)
if not data:
continue
message = data.decode()
log.debug("(NET) Received "+message)
def send(self, data):
self.loop.run_until_complete(asyncio.ensure_future(self._send(data),
loop=self.loop))
async def _send(self, data):
self.writer.write(data)
await self.writer.drain()
print("_send done")
def disconnect(self):
print("DC")
self.loop.close()
def main():
pygame.init()
screen = pygame.display.set_mode((640, 480))
pygame.display.set_caption("Pyond client")
bg = Surface((640, 480))
bg.fill(Color("#004400"))
client = Client('127.0.0.1', 2508)
while True:
pygame.event.pump()
for e in pygame.event.get():
if e.type == QUIT:
raise SystemExit
elif e.type == KEYUP:
if e.key == K_UP:
client.send(b"{'Hello':'World'}")
screen.blit(bg, (0, 0))
pygame.display.update()
client.disconnect()
if __name__ == "__main__":
main()
This code creates 640x480 window with pygame, then reads for incoming K_UP (up arrow) key. Upon pressing, sends json-like string to the server. _handle_packets was supposed to read any incoming data from server and just print it.
I was testing this code and sending works okay, but receiving is quite delayed. I'm sure I need to put handler somewhere else, so where exactly?
And btw, send works only once. Need help on this one too.
A couple of problems here.
The first one is pretty fundamental. The asycnio event loop stops running after create_client() finishes, and only runs again while you send() data. So, the only time it is able to run _handle_packets is when you are send()ing. Ideally, you should start the event loop once in a higher scope and close it once you are done with everything.
The second problem is that whenever you client.send(b"{'Hello':'World'}"), you will block the outer pygame while True loop, preventing any other events to be processed until the previous one is sent. You should make use of a asyncio.Queue to queue the events & send them from the Client class.
Here are some changes I would make (sorry, untested; I don't have pygame installed ATM):
# vim: tabstop=4 expandtab
import asyncio
import pygame
import logging
from pygame import *
log = logging.getLogger('')
class Client:
def __init__(self, host, port, loop):
self.host = host
self.port = port
self.loop = loop
self.send_q = asyncio.Queue()
async def connect(self):
self.reader, self.writer = await asyncio.open_connection(self.host,
self.port,
loop=self.loop)
self.loop.create_task(self._handle_packets())
self.loop.create_task(self._send())
async def _handle_packets(self):
while True:
data = await self.reader.read(4096)
if not data:
continue
message = data.decode()
log.debug("(NET) Received "+message)
def send(self, data):
self.send_q.put_nowait(data)
async def _send(self):
while True:
data = await self.send_q.get()
self.writer.write(data)
await self.writer.drain()
def disconnect(self):
print("DC")
self.writer.close()
async def main(loop):
pygame.init()
screen = pygame.display.set_mode((640, 480))
pygame.display.set_caption("Pyond client")
bg = Surface((640, 480))
bg.fill(Color("#004400"))
client = Client('127.0.0.1', 2508, loop)
await client.connect()
while True:
pygame.event.pump()
for e in pygame.event.get():
if e.type == QUIT:
raise SystemExit
elif e.type == KEYUP:
if e.key == K_UP:
client.send(b"{'Hello':'World'}")
screen.blit(bg, (0, 0))
pygame.display.update()
client.disconnect()
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(main(loop))
loop.close()
Another important thing to keep in mind is that you should never block the asyncio event loop with pygame, otherwise the Client network processing in the background will stall. I've never used pygame, so I'm not familiar with which pygame function might be "blocking", but they should be called using result = await loop.run_in_executor(None, blocking_func, *func_args). This will call blocking functions in another thread.
I have a function, that should do report, if test function success.
But, I don't want to do report, if there is an Exception inside test function.
I try to use pytest.fixture, pytest.yield_fixture, but all of them always call finalizers. How can I understand, that Exception had been raised in test function?
test.py StatisticClass: start
FStatisticClass: stop
finalizer
contest of test.py:
#pytest.mark.usefixtures("statistic_maker")
def test_dummy():
raise Exception()
content of conftest.py:
class StatisticClass():
def __init__(self, req):
self.req = req
pass
def start(self):
print "StatisticClass: start"
def stop(self):
print "StatisticClass: stop"
def if_not_exception(self):
"""
I don't want to call this if Exception inside yield.
Maybe, there is any info in request object?
"""
print "finalizer"
#pytest.yield_fixture(scope="function")
def statistic_maker(request):
ds = StatisticClass(request)
ds.start()
request.addfinalizer(ds.if_not_exception)
yield
ds.stop()
P.S. I can't use decorator because, I use fixture.
In Django I often assert the number of queries that should be made so that unit tests catch new N+1 query problems
from django import db
from django.conf import settings
settings.DEBUG=True
class SendData(TestCase):
def test_send(self):
db.connection.queries = []
event = Events.objects.all()[1:]
s = str(event) # QuerySet is lazy, force retrieval
self.assertEquals(len(db.connection.queries), 2)
In in SQLAlchemy tracing to STDOUT is enabled by setting the echo flag on
engine
engine.echo=True
What is the best way to write tests that count the number of queries made by SQLAlchemy?
class SendData(TestCase):
def test_send(self):
event = session.query(Events).first()
s = str(event)
self.assertEquals( ... , 2)
I've created a context manager class for this purpose:
class DBStatementCounter(object):
"""
Use as a context manager to count the number of execute()'s performed
against the given sqlalchemy connection.
Usage:
with DBStatementCounter(conn) as ctr:
conn.execute("SELECT 1")
conn.execute("SELECT 1")
assert ctr.get_count() == 2
"""
def __init__(self, conn):
self.conn = conn
self.count = 0
# Will have to rely on this since sqlalchemy 0.8 does not support
# removing event listeners
self.do_count = False
sqlalchemy.event.listen(conn, 'after_execute', self.callback)
def __enter__(self):
self.do_count = True
return self
def __exit__(self, *_):
self.do_count = False
def get_count(self):
return self.count
def callback(self, *_):
if self.do_count:
self.count += 1
Use SQLAlchemy Core Events to log/track queries executed (you can attach it from your unit tests so they don't impact your performance on the actual application:
event.listen(engine, "before_cursor_execute", catch_queries)
Now you write the function catch_queries, where the way depends on how you test. For example, you could define this function in your test statement:
def test_something(self):
stmts = []
def catch_queries(conn, cursor, statement, ...):
stmts.append(statement)
# Now attach it as a listener and work with the collected events after running your test
The above method is just an inspiration. For extended cases you'd probably like to have a global cache of events that you empty after each test. The reason is that prior to 0.9 (current dev) there is no API to remove event listeners. Thus make one global listener that accesses a global list.
what about the approach of using flask_sqlalchemy.get_debug_queries() btw. this is the methodology used by internal of Flask Debug Toolbar check its source
from flask_sqlalchemy import get_debug_queries
def test_list_with_assuring_queries_count(app, client):
with app.app_context():
# here generating some test data
for _ in range(10):
notebook = create_test_scheduled_notebook_based_on_notebook_file(
db.session, owner='testing_user',
schedule={"kind": SCHEDULE_FREQUENCY_DAILY}
)
for _ in range(100):
create_test_scheduled_notebook_run(db.session, notebook_id=notebook.id)
with app.app_context():
# after resetting the context call actual view we want asserNumOfQueries
client.get(url_for('notebooks.personal_notebooks'))
assert len(get_debug_queries()) == 3
keep in mind that for having reset context and count you have to call with app.app_context() before the exact stuff you want to measure.
Slightly modified version of #omar-tarabai's solution that removes the event listener when exiting the context:
from sqlalchemy import event
class QueryCounter(object):
"""Context manager to count SQLALchemy queries."""
def __init__(self, connection):
self.connection = connection.engine
self.count = 0
def __enter__(self):
event.listen(self.connection, "before_cursor_execute", self.callback)
return self
def __exit__(self, *args, **kwargs):
event.remove(self.connection, "before_cursor_execute", self.callback)
def callback(self, *args, **kwargs):
self.count += 1
Usage:
with QueryCounter(session.connection()) as counter:
session.query(XXX).all()
session.query(YYY).all()
print(counter.count) # 2
I've just started using SQLAlchemy a few days ago and right now I'm stuck with a problem that I hope anyone can shed some light on before I loose all my hair.
When I run a unittest, see snippet below, only the first test in the sequence is passing. The test testPhysicalPrint works just fine, but testRecordingItem fails with NoResultFound exception - No row was found for one(). But if I remove testPhysicalPrint from the test class, then testRecordingItem works.
I assume that the problem has something to do with the session, but I can't really get a grip of it.
In case anyone wonders, the setup is as follows:
Python 3.1 (Ubuntu 10.04 package)
SQLAlchemy 0.7.2 (easy_install:ed)
PostgreSQL 8.4.8 (Ubuntu 10.04 package)
PsycoPG2 2.4.2 (easy_installed:ed)
Exemple test:
class TestSchema(unittest.TestCase):
test_items = [
# Some parent class products
PrintItem(key='p1', title='Possession', dimension='30x24'),
PrintItem(key='p2', title='Andrzej Żuławski - a director', dimension='22x14'),
DigitalItem(key='d1', title='Every Man His Own University', url='http://www.gutenberg.org/files/36955/36955-h/36955-h.htm'),
DigitalItem(key='d2', title='City Ballads', url='http://www.gutenberg.org/files/36954/36954-h/36954-h.htm'),
]
def testPrintItem(self):
item = self.session.query(PrintItem).filter(PrintItem.key == 'p1').one()
assert item.title == 'Possession', 'Title mismatch'
def testDigitalItem(self):
item2 = self.session.query(DigitalItem).filter(DigitalItem.key == 'd2').one()
assert item2.title == 'City Ballads', 'Title mismatch'
def setUp(self):
Base.metadata.create_all()
self.session = DBSession()
self.session.add_all(self.test_items)
self.session.commit()
def tearDown(self):
self.session.close()
Base.metadata.drop_all()
if __name__ == '__main__':
unittest.main()
UPDATE
Here is the working code snippet.
# -*- coding: utf-8 -*-
import time
import unittest
from sqlalchemy import *
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import *
Base = declarative_base()
engine = create_engine('sqlite:///testdb', echo=False)
DBSession = sessionmaker(bind=engine)
class ItemMixin(object):
"""
Commons attributes for items, ie books, DVD:s...
"""
__tablename__ = 'testitems'
__table_args__ = {'extend_existing':True}
id = Column(Integer, autoincrement=True, primary_key=True)
key = Column(Unicode(16), unique=True, nullable=False)
title = Column(UnicodeText, default=None)
item_type = Column(Unicode(20), default=None)
__mapper_args__ = {'polymorphic_on': item_type}
def __init__(self, key, title=None):
self.key = key
self.title = title
class FooItem(Base, ItemMixin):
foo = Column(UnicodeText, default=None)
__mapper_args__ = {'polymorphic_identity':'foo'}
def __init__(self, foo=None, **kwargs):
ItemMixin.__init__(self, **kwargs)
self.foo = foo
class BarItem(Base, ItemMixin):
bar = Column(UnicodeText, default=None)
__mapper_args__ = {'polymorphic_identity':'bar'}
def __init__(self, bar=None, **kwargs):
ItemMixin.__init__(self, **kwargs)
self.bar = bar
# Tests
class TestSchema(unittest.TestCase):
# Class variables
is_setup = False
session = None
metadata = None
test_items = [
FooItem(key='f1', title='Possession', foo='Hello'),
FooItem(key='f2', title='Andrzej Żuławsk', foo='World'),
BarItem(key='b1', title='Wikipedia', bar='World'),
BarItem(key='b2', title='City Ballads', bar='Hello'),
]
def testFooItem(self):
print ('Test Foo Item')
item = self.__class__.session.query(FooItem).filter(FooItem.key == 'f1').first()
assert item.title == 'Possession', 'Title mismatch'
def testBarItem(self):
print ('Test Bar Item')
item = self.__class__.session.query(BarItem).filter(BarItem.key == 'b2').first()
assert item.title == 'City Ballads', 'Title mismatch'
def setUp(self):
if not self.__class__.is_setup:
self.__class__.session = DBSession()
self.metadata = Base.metadata
self.metadata.bind = engine
self.metadata.drop_all() # Drop table
self.metadata.create_all() # Create tables
self.__class__.session.add_all(self.test_items) # Add data
self.__class__.session.commit() # Commit
self.__class__.is_setup = True
def tearDown(self):
if self.__class__.is_setup:
self.__class__.session.close()
# Just for Python >=2.7 or >=3.2
#classmethod
def setUpClass(cls):
pass
#Just for Python >=2.7 or >=3.2
#classmethod
def tearDownClass(cls):
pass
if __name__ == '__main__':
unittest.main()
The most likely reason for this behavior is the fact that that data is not properly cleaned up between the tests. This explains why when you run only one test, it works.
setUp is called before every test, and tearDown - after.
Depending on what you would like to achieve, you have two options:
create data only once for all test.
In this case you if you had Python-2.7+ or Python-3.2+, you could use tearDownClass method. In your case you can handle it with a boolean class variable to prevent the code you have in setUp running more then once.
re-create data before every test
In this case you need to make sure that in the tearDown you delete all the data. This is what you are not doing right now, and I suspect that when the second test is ran, the call to one() fails not because it does not find an object, but because it finds more two objects matching the criteria.
Check the output of this code to understand the call sequence:
import unittest
class TestSchema(unittest.TestCase):
def testOne(self):
print '==testOne'
def testTwo(self):
print '==testTwo'
def setUp(self):
print '>>setUp'
def tearDown(self):
print '<<tearDown'
#classmethod
def setUpClass():
print '>>setUpClass'
#classmethod
def tearDownClass():
print '<<tearDownClass'
if __name__ == '__main__':
unittest.main()
Output:
>>setUp
==testOne
<<tearDown
>>setUp
==testTwo
<<tearDown
I have this as my tearDown method and it does work fine for my tests:
def tearDown (self):
"""Cleans up after each test case."""
sqlalchemy.orm.clear_mappers()