Use testing methods in Eclipse

Asked by Martin D

How would I implement tests, similar to these ones http://sikuli.org/examples/TestJEdit.sikuli/TestJEdit.html in Eclipse?
When I for example try to enter the method "wait(...)" it tells me that variable 'wait' is not defined. I can, however, use openApp and everything.

Question information

Language:
English Edit question
Status:
Solved
For:
SikuliX Edit question
Assignee:
No assignee Edit question
Solved by:
RaiMan
Solved:
Last query:
Last reply:
Revision history for this message
pyCoder (validcode-ye) said :
#1

wait is a method of Region. eclipse want to see Region.wait().

Region - http://sikuli.org/docx/region.html#Region.Region
wait - http://sikuli.org/docx/region.html#Region.wait

Revision history for this message
pyCoder (validcode-ye) said :
#2

meaning create a Region object and then eclipse's code completion will pick up that there is a method defined

#in eclipse

from sikuli.Sikuli import * #@UnusedWildImport

#reg = Region(x, y, w, h)

reg = Region(50, 34, 34, 34)

reg.wait(3)
print 'hello'

Revision history for this message
pyCoder (validcode-ye) said :
#3

you can also do this in eclipse because when the script is exicuted it goes through the normal sikuli processes. but i'm not sure how this might affect your test scripts. You can suppress eclipse's own warnings.

wait(3) #@UndefinedVariable

Revision history for this message
Martin D (martinomat) said :
#4

Thanks. So if I wanted to have something like this

openApp("/Applications/jEdit.app")
wait("", 20000)
close = ("")
if find(close):
    click(close)

I would pass a path to a screenshot to wait and close?

Revision history for this message
pyCoder (validcode-ye) said :
#5

your answer to your question....

1) yes, you pass a path to those methods.

extra crap....

2) find vs exists..... what do you want to happen if the target image is not found? do you want it to throw or return None? Design, descision.
find() - http://sikuli.org/docx/region.html#Region.find
exists() - http://sikuli.org/docx/region.html#Region.exists

3) getLastMatch() - http://sikuli.org/docx/region.html#Region.getLastMatch This is a preformance change to your code. Your telling your code hey that thing you last looked for use it and preform a click on it. so this change is not necssary.

4) write your paths like this with either '\\' or 'r' http://docs.python.org/reference/lexical_analysis.html#string-literals

r"C:\path\to\image.png"
or
"C:\\path\\to\\image.png"

optional.....

openApp("/Applications/jEdit.app")
wait("", 20000)
close = r"C:\path\to\image.png" #I' a windows guy....
if find(close):
     click(getLastMatch())

optional.....

openApp("/Applications/jEdit.app")
wait("", 20000)
if find(r"C:\path\to\image.png"):
     click(getLastMatch())

optional.....

# http://sikuli.org/docx/globals.html#addImagePath
addImagePath(r"C:\path\to\image.png") # Add all your images at the top of your script.

openApp("/Applications/jEdit.app")
wait("", 20000)
if find("image.png"): #then you can just call them byt file name
     click(getLastMatch())

Revision history for this message
pyCoder (validcode-ye) said :
#6

opps... you add directories that contain your images... sorry was on copy past tangent.

# http://sikuli.org/docx/globals.html#addImagePath
 addImagePath(r"C:\path\to\") # Add all your images directories at the top of your script.

openApp("/Applications/jEdit.app")
 wait("", 20000)
 if find("image.png"): #then you can just call them byt file name
      click(getLastMatch())

Revision history for this message
Martin D (martinomat) said :
#7

I can't seem to get it working. I get some kind of exception.

Code:

from sikuli.Sikuli import *
from sikuli.SikuliTest import *
import os

os.popen(r"open /path/folder/someFile.jar")
addImagePath(r"/path/folder/images/")
reg = Region(238, 158, 804, 502)
if reg.find("test.png"):
    print "found"
else:
    print "not_found"

And get following error:

[info] Sikuli vision engine loaded.
[info] Mac OS X utilities loaded.
[info] VDictProxy loaded.
Traceback (most recent call last):
  File "/somePath/TestingSikuli/src/main.py", line 9, in <module>
    if reg.find("image.png"):
  Line 12, in file /somePath/TestingSikuli/src/main.py

 at org.sikuli.script.Region.handleFindFailed(Region.java:420)
 at org.sikuli.script.Region.wait(Region.java:511)
 at org.python.proxies.sikuli.Region$Region$0.super__wait(Unknown Source)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
 at java.lang.reflect.Method.invoke(Method.java:597)

org.sikuli.script.FindFailed: FindFailed: can not find test.png on the screen.
  Line 12, in file /somePath/TestingSikuli/src/main.py

Revision history for this message
pyCoder (validcode-ye) said :
#8

is the image visable? find() will throw an exception if it can't see it. meaning else: clause will never execute if it fails. i recomend you replace find() with exists().

then try it again.

Revision history for this message
Martin D (martinomat) said :
#9

Oh. I see. Yes, using exists() doesn't give me exceptions anymore. However, it always goes to the else case and I don't even know why, because the image is definitely there.

Here is my code sample:

from sikuli.Sikuli import *
from sikuli.SikuliTest import *
import os

switchApp("Safari")
addImagePath(r"/path/to/screens/")
reg = Region(0, 0, 1280, 800)
if reg.exists(Pattern("test2.png").similar(0.2)):
    print "found"
else:
    print "not_found"

 I even set the "similar" method to 0.000001 and it still jumps to the else case.

And the "test2.png" is just a screenshot of the Safari app. I is the exact same picture. The only difference is that my region is my whole screen, therefore I have the menu bar on top, but that is only like 5% of the picture. That's why I used the similar method, however, it doesn't seem to work. Changing similar to 0 will print out "found" of course.

Revision history for this message
RaiMan (raimund-hocke) said :
#10

--- if it is on Mac:
using Safari in fullscreen mode is not supported yet (if you use it ;-)

--- similar(0.2) ...
... does not make much sense.
Sikuli's matching works pixel by pixel and a lower similarity only means, that some of the pixels only differ in brightness or color. But the pixel structure as such must be the same.
Similarity does not mean, that parts of the image are ignored with lower similarity.
So when using Sikuli in its standard approach you have images that are smaller (in most cases much smaller) the the region they are searched in.
Here the goal is, to get similarity scores between 0.9 and 1.0, to be sure the image is really the one you are looking for (e.g. to click on it).

e.g. if you had made a screenshot of the inactive Safari window (window buttons inactive) and search it on the screen where the same Safari window would have active buttons, it would be found with a similarity towards 0.9.
visible with inactive buttons this should give a similarity towards 1.0.
But the probe must be the same size as the visible Safari window or at least a part of it that is the same pixel by pixel.
It normally does not make sense, to capture windows with its frames, since only one pixel difference in size would lead to not found.

It is another case, if you want to compare images (the image probe has the same size as the search area). This is usually used, to check, wether a whole area on the screen is the same as the shot that was made with a previous run (regression testing).

--- your case
this is how it should be in Sikuli IDE (which is Python level):

import os
switchApp("Safari")
dir = "/path/to/screens/" # r not needed here
if exists(os.path.join(dir, "test2.png")): # by default the whole screen is searched anyway
    print "found"
else:
    print "not_found"

If you want to use addImagePath in the IDE, you have to avoid that the same entry is added with every rerun again (see docs).
if you only have one image repository, the setBundlePath() might be an alternative.

--- BTW:
this is never needed in main scripts
from sikuli.Sikuli import *

this is only for internal use (regression testing of Sikuli itself) and has nothing to do with unit testing
from sikuli.SikuliTest import *

if you are interested in unit testing on the Python level:
look faq 1804

Revision history for this message
Martin D (martinomat) said :
#11

Thanks for the thorough explanation!

Now it works. Only one little thing left. If I don't initialize a region, I can't use "click", "exists" etc. without marking it with "#@UndefinedVariable".

Is there a workaround for this? If not, how do I tell region to use the whole screen, without specifying the actual resoultion, e.g. reg = Region(fullscreen) ?

Revision history for this message
Best RaiMan (raimund-hocke) said :
#12

--- #@UndefinedVariable
this is only a thing for Eclipse, to suppress the hint, that the method cannot be found.
At runtime this will work, since Sikuli in the standard automatically interprets each unqualified Region and Screen method as a method of object SCREEN, that is initialized as Screen(0) meaning the region of the primary monitor.
This is only a scripting convenience for the people using the Python level in the IDE.

To avoid these messages, you could once at the beginning of the script say
s = Screen(0)
and then always say
s.click()
if you mean the whole screen
(which would be less to write)

Revision history for this message
Martin D (martinomat) said :
#13

Thanks RaiMan, that solved my question.