Aubergine



  • So I work in test automation, and the company I work for makes a popular flash-based online game. When I started here we were using Eggplant, and I'd never done image based automation before, so it took me a while to see the issues with this product, I mean from their website it looks quite good: http://www.testplant.com/products/eggplant/



    And in fact over then the slight WTF of image based automation, eggplant itself is actually a pretty nice tool. It has varying levels of fuzziness in how you determine a match, and has inbuilt OCR etc. The issue is that there is only one interface to it for writing tests, and that would be - you might have guessed it - a home grown scripting language. Without any further comment I submit to you the user manual: http://docs.testplant.com/?q=content/sensetalk-reference



  • Doesn't seem too bad from the given examples.



  • Try this page and then imagine trying to structure something more complicated, given a syntax that unstructured. Then go onto the way that values are defined before continuing onto their implementation of prototype objects. I think though one of the most obvious wtfs was that "put empty list is empty" returns False...



  • oh my fucking god it's the rotten spiritual successor to Lingo.

    euhgeugheguguh


  • ♿ (Parody)

    My first thought: Lowercase COBOL?



  •  @theheadofabroom said:

    Try this page and then imagine trying to structure something more complicated, given a syntax that unstructured. Then go onto the way that values are defined before continuing onto their implementation of prototype objects. I think though one of the most obvious wtfs was that "put empty list is empty" returns False...

    Wow. It's like someone looked at Inform7 and thought "Good, but not ambiguous enough".



  • Numbers in SenseTalk can be written using numerals:
    1
    634
    12.908
    -3
    .5
    18.75

    or as words:
    one
    six hundred thirty-four
    twelve point zero nine eight
    negative three
    one half
    eighteen and three quarters
    Oh god.


  • This was code to set a default value in the constructor for an object:

    to DefaultTo VariableName_IfYouUseDataLikeThisYouDeserveToGetBitten, Default
    	if VariableName_IfYouUseDataLikeThisYouDeserveToGetBitten is empty or\
    			VariableName_IfYouUseDataLikeThisYouDeserveToGetBitten = \
    			"VariableName_IfYouUseDataLikeThisYouDeserveToGetBitten"
    		return Default	
    	end if
    	return VariableName_IfYouUseDataLikeThisYouDeserveToGetBitten
    end DefaultTo

    Because they used bare strings, so if a variable wasn't set, it was just the variable's name. I'm ashamed to say I thought this up, because I thought it was possible to build a sturdy house on quicksand...

    But the bit I forgot to point out was the way imports were done. No you don't do anything as nice as "import FooSuite.FooModule1" and then refer to FooSuite.FooModule1, you have to add "FooSuite" to your suite as a "helper suite" which meant that "FooModule1", "FooModule2" and "FooModule3" all get added to your top-level scope, and you can't do anything with the namespace FooModule - that doesn't exist, do don't even think about having two script files with the same name anywhere on you machine...



  • @mikeTheLiar said:

    Numbers in SenseTalk can be written using numerals:

    1

    634

    12.908

    -3

    .5

    18.75



    or as words:

    one

    six hundred thirty-four

    twelve point zero nine eight

    negative three

    one half

    eighteen and three quarters

    Oh god.

    or...
    65165851231565478123126156548956123121
    as
    sixty-five undecillion one hundred sixty-five decillion eight hundred fifty-one nonillion two hundred thirty-one octillion five hundred sixty-five septillion four hundred seventy-eight sextillion one hundred twenty-three quintillion one hundred twenty-six quadrillion one hundred fifty-six trillion five hundred forty-eight billion nine hundred fifty-six million one hundred twenty-three thousand one hundred twenty-one



  • @KattMan said:

    or... 65165851231565478123126156548956123121 as sixty-five undecillion one hundred sixty-five decillion eight hundred fifty-one nonillion two hundred thirty-one octillion five hundred sixty-five septillion four hundred seventy-eight sextillion one hundred twenty-three quintillion one hundred twenty-six quadrillion one hundred fifty-six trillion five hundred forty-eight billion nine hundred fifty-six million one hundred twenty-three thousand one hundred twenty-one
    What is that in old money?



  • @KattMan said:

    65165851231565478123126156548956123121

    Can you mix them? Like 5 thousand 7 hundred sixty 5?



  • @drurowin said:

    @KattMan said:

    or...
    65165851231565478123126156548956123121
    as
    sixty-five undecillion one hundred sixty-five decillion eight hundred fifty-one nonillion two hundred thirty-one octillion five hundred sixty-five septillion four hundred seventy-eight sextillion one hundred twenty-three quintillion one hundred twenty-six quadrillion one hundred fifty-six trillion five hundred forty-eight billion nine hundred fifty-six million one hundred twenty-three thousand one hundred twenty-one
    What is that in old money?

    Seven bob, π/2 rooks and a very small barony near Titchfield.



  • @mikeTheLiar said:

    @KattMan said:
    65165851231565478123126156548956123121

    Can you mix them? Like 5 thousand 7 hundred sixty 5?

    What do you mean mix them? This is actually the output of a quick and dirty app I put together to practice using the interpreter pattern. The numbers it can work with and translate to written values is pretty high.

    Edit
    Never mind I got it.



  • But does it use 1-based indexing, or something stupid?



  • @morbiuswilters said:

    But does it use 1-based indexing, or something stupid?

    It uses e π i + 1 indexing. Sorry.


  • Considered Harmful

    @KattMan said:

    65165851231565478123126156548956123121
    as
    sixty-five undecillion one hundred sixty-five decillion eight hundred fifty-one nonillion two hundred thirty-one octillion five hundred sixty-five septillion four hundred seventy-eight sextillion one hundred twenty-three quintillion one hundred twenty-six quadrillion one hundred fifty-six trillion five hundred forty-eight billion nine hundred fifty-six million one hundred twenty-three thousand one hundred twenty-one

    Task: Insert another digit to the end of the number.

    Estimated effort: 2 hours



  • @joe.edwards said:

    @KattMan said:
    65165851231565478123126156548956123121
    as
    sixty-five undecillion one hundred sixty-five decillion eight hundred fifty-one nonillion two hundred thirty-one octillion five hundred sixty-five septillion four hundred seventy-eight sextillion one hundred twenty-three quintillion one hundred twenty-six quadrillion one hundred fifty-six trillion five hundred forty-eight billion nine hundred fifty-six million one hundred twenty-three thousand one hundred twenty-one

    Task: Insert another digit to the end of the number.

    Estimated effort: 2 hours

    You are fired.



  • I was never masochistic enough to try that, writing and maintaining sane code was bad enough...
    @mikeTheLiar said:

    @KattMan said:
    65165851231565478123126156548956123121

    Can you mix them? Like 5 thousand 7 hundred sixty 5?



  • @morbiuswilters said:

    But does it use 1-based indexing, or something stupid?

    Of course, from the docs:

    Lists can include any type of value, including other lists and property lists. Expressions can be used in constructing lists:
    
    put ("geranium", pi * (2 * radius), (age:42)) into mixedList
    
    Combining Lists
    To join two lists as one (without nesting), the &&& operator may be used:
    
    put (3,4,5) into tr1
    -- (3,4,5)
    
    put (5,12,13) into tr2
    -- (5,12,13)
    
    put tr1 &&& tr2 into longList
    -- (3,4,5,5,12,13)
    
    put (tr1,tr2) into twoTriples
    -- ((3,4,5),(5,12,13))
    
    put (1,(2,(3,4)),5) into nestedList
    -- (1,(2,(3,4)),5)
    
    Accessing List Items
    Accessing items within lists, including ranges of items and lists of items, is fully supported using the item and items chunk expressions (or their more explicit forms, list item and list items). Accessing a single item yields the item at that index. Accessing a range of items always yields a list, even when the range specifies a single item:
    
    put (1,2,3,4,5) into list
    -- (1,2,3,4,5)
    
    put list items 3 to last of list
    -- (3,4,5)
    
    put item 2 of list
    -- 2
    
    put items 2 to 2 of list
    -- (2)
    
    put items (4,2,5) of list
    -- (4,2,5)
    
    Note that the term item will, by default, refer to text items rather than list items if the variable in question is not known to be a list. Using the explicit term list item will always treat the variable as a list even if it contains a non-list value (in which case it will be treated like a one-item list containing that value).
    
    Converting Lists to Text
    When a list needs to be accessed as text (such as when it is displayed by a put command), SenseTalk converts it automatically to a text representation. By default, this will be done by enclosing the entire list in parentheses, with the items in the list separated by commas. You can change this formatting by setting the prefix, separator, and suffix values of the listFormat global property. The prefix is the text that will be used before the list (usually a left parenthesis), separator is the text inserted between items, and suffix is the text appended after the list. These may be set to any text you like, including empty.
    
    set the listFormat to (prefix:">>", separator:":", suffix:"<<")
    
    put (1,2,3,4,5)
    -- displays >>1:2:3:4:5<<
    
    

  • Considered Harmful

    @morbiuswilters said:

    @joe.edwards said:
    @KattMan said:
    65165851231565478123126156548956123121
    as
    sixty-five undecillion one hundred sixty-five decillion eight hundred fifty-one nonillion two hundred thirty-one octillion five hundred sixty-five septillion four hundred seventy-eight sextillion one hundred twenty-three quintillion one hundred twenty-six quadrillion one hundred fifty-six trillion five hundred forty-eight billion nine hundred fifty-six million one hundred twenty-three thousand one hundred twenty-one

    Task: Insert another digit to the end of the number.

    Estimated effort: 2 hours

    You are fired.


    My estimates tend to be nearly an order of magnitude more than what I expect. Hofstadter's law and all that.



  • @joe.edwards said:

    Hofstadter's law and all that.

    Hofstadter's fired, too!



  • @morbiuswilters said:

    @joe.edwards said:
    Hofstadter's law and all that.

    Hofstadter's fired, too!


    Hofstadter's corollary: it takes longer to fire Hofstadter than you think, even if you take Hofstadter's Corollary into account.



  • @mikeTheLiar said:

    @morbiuswilters said:
    @joe.edwards said:
    Hofstadter's law and all that.

    Hofstadter's fired, too!


    Hofstadter's corollary: it takes longer to fire Hofstadter than you think, even if you take Hofstadter's Corollary into account.

    Morbs' Axiom XVI: Always think that things will take a very, very short time, to compensate for Hofstadter's Law. That way, things will take exactly as much time as they're supposed to.



  • @morbiuswilters said:

    @mikeTheLiar said:
    @morbiuswilters said:
    @joe.edwards said:
    Hofstadter's law and all that.

    Hofstadter's fired, too!


    Hofstadter's corollary: it takes longer to fire Hofstadter than you think, even if you take Hofstadter's Corollary into account.

    Morbs' Axiom XVI: Always think that things will take a very, very short time, to compensate for Hofstadter's Law. That way, things will take exactly as much time as they're supposed to.

    Ben's Axiom I Processes take an arbitrary amount of time to complete. Estimate the bitwise complement of zero seconds. As technology becomes more powerful, you'll have (exponentially) more billable hours!



  • @joe.edwards said:

    My estimates tend to be nearly an order of magnitude more than what I expect. Hofstadter's law and all that.

    There's an actual law for that? I just picked that up from the TNG episode with Scotty.



  • I just came across a question I asked on the Stack Exchange SQA site...


    Sensetalk - Eggplant's scripting language, leaves a lot to be desired. I do not personally see why people feel the need to invent new languages all the time. The syntax is overly simplistic, and as such can turn anything that is not simple into a lisp-like mess of parentheses in order to be sure what it will do. Some basic language features such as default parameters are missing and need to be engineered into your scripts. Behaviour for uninitialised variables is utterly broken - Sensetalk will silently do what it thinks is best - `UninitialisedVar` is read as `"UninitialisedVar"`, however `A phrase that has not been escaped in quotes` may or may not throw a syntax error depending on what out of that phrase has been initialised and what type it has been initialised to.

    Any hints and tips on using Sensetalk effectively?


    From my short time to date (about a month) using sensetalk I have come up with the following:

    1. Booleans are lazily evaluated from Right to Left (<-), not Left to Right (->) as in most common languages. This means that if you do `if func1() and func0() then return True else return False` then in the case that `func0` returns `False` `func1` will not be evaluated - this is the reverse of most languages where `func1` would be evaluated first and you could short-circuit `func0`. Similarly for `if func1() or func0() return True else return false` `func1` will only be evaluated if `func0` returns `False`.
    2. If you want to use strings, make sure you use quotes around them - the behaviour whereby uninitialised variables are seen as strings is completely borked - avoid it.
    3. Write generic helper scripts - while there are some fairly complex things that Sensetalk/Eggplant will do without breaking a sweat, there are some fairly fundamental things that are missing from the language. Write them and keep them in a helper suite, you will find yourself using them all over the place.
    4. Sensetalk has no default parameters (AFAIK) write your own. I have the following helper function:
      to DefaultTo VariableNameIfYouUseDataLikeThisYouDeserveToGetBitten, Default
          if VariableNameIfYouUseDataLikeThisYouDeserveToGetBitten is empty\
          or VariableNameIfYouUseDataLikeThisYouDeserveToGetBitten = "VariableNameIfYouUseDataLikeThisYouDeserveToGetBitten"\
                then return Default
                return VariableNameIfYouUseDataLikeThisYouDeserveToGetBitten
           end DefaultTo
      I use this everywhere in the form of:
      to Blah Var1, Var2, Var3
          set Var1 to DefaultTo(Var1, SensibleDefaultVar1)
          set Var2 to DefaultTo(Var2, SensibleDefaultVar2)
          set Var3 to DefaultTo(Var3, SensibleDefaultVar3)
      end Blah
    5. It is very easy to write automated steps that perform an action, however using these to test something is left as an exercise to you - not necessarily a bad thing but *make sure that the person architecting the project knows their stuff*.
    6. Sensetalk and Eggplant pose few restrictions on how you approach automated testing other than those integral to the way they work (image capture and recognition over VNC), however *make sure that the person architecting the project knows their stuff* or it is all too easy to end up with a complicated mess.
    7. Eggplant's performance can be unpredictable - some things are very slow, others are surprisingly fast - you should play about with a few implementations of what you want to do rather than making any assumptions about performance.


  • Why do people name computer languages after food, animals, and/or imperative verbs?

     



  • @too_many_usernames said:

    Why do people name computer languages after food, animals, and/or imperative verbs?

    Sometimes it's all three: Duck.


Log in to reply