Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.java.programmer > #37825 > unrolled thread
| Started by | Kiwi User <martin@mydomain.invalid> (Kiwi User) |
|---|---|
| First post | 2017-12-12 16:31 +1200 |
| Last post | 2017-12-16 09:08 +0000 |
| Articles | 16 — 5 participants |
Back to article view | Back to comp.lang.java.programmer
Re: Calling deprecated methods Kiwi User <martin@mydomain.invalid> (Kiwi User) - 2017-12-12 16:31 +1200
Re: Calling deprecated methods Eric Douglas <e.d.programmer@gmail.com> (Eric Douglas) - 2017-12-12 10:24 +1200
Re: Calling deprecated methods Kiwi User <martin@mydomain.invalid> (Kiwi User) - 2017-12-12 20:05 +1200
Re: Calling deprecated methods Eric Sosman <esosman@comcast-dot-net.invalid> (Eric Sosman) - 2017-12-12 15:41 +1200
Re: Calling deprecated methods Kiwi User <martin@mydomain.invalid> (Kiwi User) - 2017-12-12 21:04 +1200
Re: Calling deprecated methods Eric Douglas <e.d.programmer@gmail.com> (Eric Douglas) - 2017-12-12 13:33 +1200
Re: Calling deprecated methods Kiwi User <martin@mydomain.invalid> (Kiwi User) - 2017-12-12 22:41 +1200
Re: Calling deprecated methods Eric Sosman <esosman@comcast-dot-net.invalid> (Eric Sosman) - 2017-12-12 17:57 +1200
Re: Calling deprecated methods Eric Douglas <e.d.programmer@gmail.com> (Eric Douglas) - 2017-12-13 04:51 +1200
Re: Calling deprecated methods Eric Sosman <esosman@comcast-dot-net.invalid> (Eric Sosman) - 2017-12-13 08:21 +1200
Re: Calling deprecated methods Eric Douglas <e.d.programmer@gmail.com> (Eric Douglas) - 2017-12-13 05:40 +1200
Re: Calling deprecated methods Kiwi User <martin@mydomain.invalid> (Kiwi User) - 2017-12-13 15:19 +1200
Re: Calling deprecated methods Eric Douglas <e.d.programmer@gmail.com> (Eric Douglas) - 2017-12-13 07:57 +1200
Re: Calling deprecated methods Kiwi User <martin@mydomain.invalid> (Kiwi User) - 2017-12-13 17:30 +1200
Re: Calling deprecated methods Richard Damon <Richard@Damon-Family.org> - 2017-12-15 22:31 -0500
Re: Calling deprecated methods Kiwi User <martin@mydomain.invalid> - 2017-12-16 09:08 +0000
| From | Kiwi User <martin@mydomain.invalid> (Kiwi User) |
|---|---|
| Date | 2017-12-12 16:31 +1200 |
| Subject | Re: Calling deprecated methods |
| Message-ID | <2726543365@f38.n261.z1.binkp.net> |
On Tue, 12 Dec 2017 08:09:11 -0800, Eric Douglas wrote:
> I always thought deprecating a method means there is a different method
> signature that is recommended to call that is going to do the same thing
> in a better way, and all calls to the old method should be changed asap?
>
Don't forget that a deprecated method isn't replaced by a drop-in replacement:
if such a replacement is possible, you'd merely scrape out the old code and
drop in the new. No deprecation needed. A good example would be upgrading a
sort() method from the bubble sort to the quicksort algorithm.
Deprecated methods tend to have a revised API, i.e. returning a Collection or a
List instead of an array, so you'd want to deprecate the older method as an
indication that Java now provides better ways of handling data passed to or
from the method, i.e. if our sort() method now returns a List or Collection
instead of Object[].
> Does it make sense to just keep calling the deprecated method and have
> to tell your compiler to ignore that, or why would Oracle deprecate
> their own method they're still calling?
>
Yes, they would and have deprecated their own methods, usually for the sort of
reasons I've just used as examples.
--
Martin | martin at
Gregorie | gregorie
| dot org
[toc] | [next] | [standalone]
| From | Eric Douglas <e.d.programmer@gmail.com> (Eric Douglas) |
|---|---|
| Date | 2017-12-12 10:24 +1200 |
| Message-ID | <2761950898@f38.n261.z1.binkp.net> |
| In reply to | #37825 |
On Tuesday, December 12, 2017 at 11:32:12 AM UTC-5, Kiwi User wrote: > Deprecated methods tend to have a revised API, i.e. returning a > Collection or a List instead of an array, so you'd want to deprecate the > older method as an indication that Java now provides better ways of > handling data passed to or from the method, i.e. if our sort() method > now returns a List or Collection instead of Object[]. > Sometimes you have to make a new method because you're changing the parameters or return value, possible also just making a new method because better internals and some cases where the new guts just don't work and you have to stick with the old. > > Does it make sense to just keep calling the deprecated method and have > > to tell your compiler to ignore that, or why would Oracle deprecate > > their own method they're still calling? > > > Yes, they would and have deprecated their own methods, usually for the > sort of reasons I've just used as examples. > The fact they deprecated a method isn't a problem. The fact they're still calling it is questionable. javax.swing.JTree calls java.awt.event.MouseEvent.getModifiers() which is marked deprecated in Java 9. So now I'm doing something similar to what the JTree class is doing, with a control overlapping a JTree trying to forward mouse events by creating new events from existing events and I'm not sure how to do that without called getModifiers(). Javadoc on getModifiers() says to use getModifiersEx() for some reason but yes it's certainly not a drop in replacement. It compiles if you straight up change it to that but then the mouse clicks to expand/collapse a tree node don't work.
[toc] | [prev] | [next] | [standalone]
| From | Kiwi User <martin@mydomain.invalid> (Kiwi User) |
|---|---|
| Date | 2017-12-12 20:05 +1200 |
| Message-ID | <1547161071@f38.n261.z1.binkp.net> |
| In reply to | #37826 |
On Tue, 12 Dec 2017 10:24:50 -0800, Eric Douglas wrote:
> On Tuesday, December 12, 2017 at 11:32:12 AM UTC-5, Kiwi User wrote:
>> Deprecated methods tend to have a revised API, i.e. returning a
>> Collection or a List instead of an array, so you'd want to deprecate
>> the older method as an indication that Java now provides better ways of
>> handling data passed to or from the method, i.e. if our sort() method
>> now returns a List or Collection instead of Object[].
>>
> Sometimes you have to make a new method because you're changing the
> parameters or return value,
>
Thats what 'revised API' means. In C I'd call it a revised prototype.
> possible also just making a new method
> because better internals and some cases where the new guts just don't
> work and you have to stick with the old.
>
IMHO that's never a valid reason: you should have a test harness for the
class, and preferably a set of regression tests as well. The revised code
should not be checked into the VCS or made visible outside the revising
programmer's personal login environment until it has been (a) fully tested and
(b) if the method specs didn't change, has passed the current set of regression
tests.
> The fact they deprecated a method isn't a problem. The fact they're
> still calling it is questionable. javax.swing.JTree calls
> java.awt.event.MouseEvent.getModifiers() which is marked deprecated in
> Java 9.
>
Agreed. At a minimum, everything in the package should use the replacement
class/method and preferably all code in the next release should use it too.
This is the "eat your own dogfood" principle and I'm suspicious of those who
don't stick to it.
--
Martin | martin at
Gregorie | gregorie
| dot org
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> (Eric Sosman) |
|---|---|
| Date | 2017-12-12 15:41 +1200 |
| Message-ID | <1640994863@f38.n261.z1.binkp.net> |
| In reply to | #37838 |
On 12/12/2017 3:05 PM, Kiwi User wrote:
> On Tue, 12 Dec 2017 10:24:50 -0800, Eric Douglas wrote:
>> [...]
>> The fact they deprecated a method isn't a problem. The fact they're
>> still calling it is questionable. javax.swing.JTree calls
>> java.awt.event.MouseEvent.getModifiers() which is marked deprecated in
>> Java 9.
>>
> Agreed. At a minimum, everything in the package should use the
> replacement class/method and preferably all code in the next release
> should use it too.
>
> This is the "eat your own dogfood" principle and I'm suspicious of those
> who don't stick to it.
Bear in mind that Java 9 was originally scheduled for 2016,
then postponed to 2017 Spring, then 2017 Summer, and finally to 2017 Autumn,
more than a year later than planned.[*] Resistance to the Project Jigsaw
changes can be blamed for only part of the delay; we may imagine that there was
a lot of work to be done and that it took substantially longer than expected.
Deadline pressure being what it is, I don't find it surprising that the final
product was not quite as polished as might have been hoped; it's quite possible
that a goodly number of lower-priority tasks were deferred to Another Time.
Java's GUI technologies might well be considered among the lower-priority
pieces ...
[*] A colleague once explained his method for making sense of
software project time estimates. An estimate always consists of two parts: A
quantity and a time unit, like "two weeks" or "six months." My colleague would
start by doubling the quantity, then continue by bumping the time unit up by
one step. Thus, the examples above would be understood as "four months" and
"twelve years." ;)
--
esosman@comcast-dot-net.invalid
Eleven hundred thirty-five days to go.
[toc] | [prev] | [next] | [standalone]
| From | Kiwi User <martin@mydomain.invalid> (Kiwi User) |
|---|---|
| Date | 2017-12-12 21:04 +1200 |
| Message-ID | <296763448@f38.n261.z1.binkp.net> |
| In reply to | #37839 |
On Tue, 12 Dec 2017 15:41:40 -0500, Eric Sosman wrote:
> Bear in mind that Java 9 was originally scheduled for 2016,
> then postponed to 2017 Spring, then 2017 Summer, and finally to 2017
> Autumn, more than a year later than planned.[*]
>
Then they had plenty of time to get it right, didn't they.
> Resistance to the Project Jigsaw changes can be blamed for only part of
> the delay;
>
Sure, but I wasn't really taking aim at Oracle: I have little doubt that
they'll have reasonable regression test coverage and will maintain that
regression test suite.
In the past I've seen far too many sets of local library support functions that
had no documentation, test harnesses or regression test data and was
suggesting that devs in general should not go there.
This was common in the past when we didn't know any better, but now we do.
However, it wouldn't surprise me that many PHBs (who are probably MBAs) still
consider test harnesses and regression testing to be a waste
of time.
> [*] A colleague once explained his method for making sense of
> software project time estimates. An estimate always consists of two
> parts: A quantity and a time unit, like "two weeks" or "six months." My
> colleague would start by doubling the quantity, then continue by bumping
> the time unit up by one step. Thus, the examples above would be
> understood as "four months" and "twelve years." ;)
>
... good to see there are no cynics round here.
--
Martin | martin at
Gregorie | gregorie
| dot org
[toc] | [prev] | [next] | [standalone]
| From | Eric Douglas <e.d.programmer@gmail.com> (Eric Douglas) |
|---|---|
| Date | 2017-12-12 13:33 +1200 |
| Message-ID | <2163157443@f38.n261.z1.binkp.net> |
| In reply to | #37840 |
On Tuesday, December 12, 2017 at 4:04:55 PM UTC-5, Kiwi User wrote: > > Bear in mind that Java 9 was originally scheduled for 2016, > > then postponed to 2017 Spring, then 2017 Summer, and finally to 2017 > > Autumn, more than a year later than planned.[*] > > > Then they had plenty of time to get it right, didn't they. > > > Resistance to the Project Jigsaw changes can be blamed for only part of > > the delay; > > > Sure, but I wasn't really taking aim at Oracle: I have little doubt that > they'll have reasonable regression test coverage and will maintain that > regression test suite. > > In the past I've seen far too many sets of local library support > functions that had no documentation, test harnesses or regression test > data and was suggesting that devs in general should not go there. > > This was common in the past when we didn't know any better, but now we > do. However, it wouldn't surprise me that many PHBs (who are probably > MBAs) still consider test harnesses and regression testing to be a waste > of time. > > > [*] A colleague once explained his method for making sense of > > software project time estimates. An estimate always consists of two > > parts: A quantity and a time unit, like "two weeks" or "six months." My > > colleague would start by doubling the quantity, then continue by bumping > > the time unit up by one step. Thus, the examples above would be > > understood as "four months" and "twelve years." ;) > > > ... good to see there are no cynics round here. > Development time = number of developers * skill of developers * scope of project? How many bugs are there to be fixed? How many enhancement requests? How many requests must be handled by a single developer or development team? Is there a framework and standard for testing? Is each developer or development team responsible for their own testing? Is anyone outside the company using the API? Does the company place importance on stability, maintainability, versatility? I suspect a lot of developers write code that is not well tested, not well documented and/or hard to maintain if the company doesn't enforce standards for it. Hard to maintain means job security. Not well tested means showing results faster, assuming it's not going to crash and hurt your career. Not well documented means getting results faster, assuming you're not worried about wasting your own time by having to modify what you've done previously after you've forgotten how it works. I suspect most businesses never look at their developers' code and give performance reviews based on how much of their work has gone live, no pat on the back for pretty and detailed comment blocks. Sometimes that does require peer review, as I'm not writing comment blocks for a section of code that seems obvious, though to another developer it may not be so obvious. I currently work for a small business, so not a lot of time to waste writing tests that can guarantee every enhancement won't break any existing code much less comment blocks, when we have a dozen big enhancement requests and 2 developers. Delays in the release schedule mean the code should be cleaner, only if the initial release schedule wasn't overly ambitious to begin with, and if the project wasn't inundated with change requests along the way.
[toc] | [prev] | [next] | [standalone]
| From | Kiwi User <martin@mydomain.invalid> (Kiwi User) |
|---|---|
| Date | 2017-12-12 22:41 +1200 |
| Message-ID | <3801429685@f38.n261.z1.binkp.net> |
| In reply to | #37843 |
On Tue, 12 Dec 2017 13:33:06 -0800, Eric Douglas wrote:
> I currently work for a small business, so not a lot of time to waste
> writing tests that can guarantee every enhancement won't break any
> existing code much less comment blocks, when we have a dozen big
> enhancement requests and 2 developers.
>
If a class is largely getters and setters and its other methods for linear
things, then you're right.
However, if there are ANY edge cases and/or errors to be handled, then just
writing it and incorporating calls for in in the application code is likely to
bite your bum because (a) unit/system test of the combined code module may
never exercise all its edge cases due to inadequate test data and (c) once a
user starts trying something the system designer never thought of and generates
the edge case, it may take a lot of time and effort merely to determine what
happened and which module crashed.
Using a test harness will probably save time and effort overall because: such
harnesses are typically very fast to write: once you've got a test harness
skeleton running, the code needed to interface it to a new class is almost a
script and the incremental code within that which tests a method is 2-4 lines
plus the actual method call. Last but not least, its dead easy to set up test
date that can deal with all normal and abnormal inputs AND contains (comments)
to show whether each method test in the script should succeed or fail and what
the expected results should be.
On top of that, once you have a set of tests set up, they tend to be fast and
easy to run, so its practical, and worthwhile to rerun them after and change is
made to the class. I have sets of 30-50 regression tests that execute in under
a second and will, if done properly, inadvertant mistakes made when you're in
a hurry.
Been there, done that, got the benefits.
--
Martin | martin at
Gregorie | gregorie
| dot org
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> (Eric Sosman) |
|---|---|
| Date | 2017-12-12 17:57 +1200 |
| Message-ID | <3931514869@f38.n261.z1.binkp.net> |
| In reply to | #37845 |
On 12/12/2017 5:41 PM, Kiwi User wrote:
> On Tue, 12 Dec 2017 13:33:06 -0800, Eric Douglas wrote:
>
>> I currently work for a small business, so not a lot of time to waste
>> writing tests that can guarantee every enhancement won't break any
>> existing code much less comment blocks, when we have a dozen big
>> enhancement requests and 2 developers.
>>
> If a class is largely getters and setters and its other methods for
> linear things, then you're right.
... or mostly right. A setter that is supposed to enforce a
restriction like "the value must be strictly positive" should be tested to
ensure that it does in fact throw the proper exception. Similarly for setters
with state dependencies like "the value can be changed at will before the
doItNowBabe() method is called, but cannot be changed thereafter."
> [... good advice about test harnesses ...]
> Been there, done that, got the benefits.
Ditto, seconded, and Aayy-men!
--
esosman@comcast-dot-net.invalid
Eleven hundred thirty-five days to go.
[toc] | [prev] | [next] | [standalone]
| From | Eric Douglas <e.d.programmer@gmail.com> (Eric Douglas) |
|---|---|
| Date | 2017-12-13 04:51 +1200 |
| Message-ID | <1795335397@f38.n261.z1.binkp.net> |
| In reply to | #37846 |
On Tuesday, December 12, 2017 at 5:57:21 PM UTC-5, Eric Sosman wrote: > ... or mostly right. A setter that is supposed to enforce a > restriction like "the value must be strictly positive" should be > tested to ensure that it does in fact throw the proper exception. > Similarly for setters with state dependencies like "the value can > be changed at will before the doItNowBabe() method is called, but > cannot be changed thereafter." > > > [... good advice about test harnesses ...] > > Been there, done that, got the benefits. > > Ditto, seconded, and Aayy-men! Interaction is sometimes the hard part of testing. Method A works fine, unless you've called Method B with value C then Method D with value E first?
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> (Eric Sosman) |
|---|---|
| Date | 2017-12-13 08:21 +1200 |
| Message-ID | <2472835388@f38.n261.z1.binkp.net> |
| In reply to | #37847 |
On 12/13/2017 7:51 AM, Eric Douglas wrote:
> On Tuesday, December 12, 2017 at 5:57:21 PM UTC-5, Eric Sosman wrote:
>> ... or mostly right. A setter that is supposed to enforce a
>> restriction like "the value must be strictly positive" should be
>> tested to ensure that it does in fact throw the proper exception.
>> Similarly for setters with state dependencies like "the value can
>> be changed at will before the doItNowBabe() method is called, but
>> cannot be changed thereafter."
>>
>>> [... good advice about test harnesses ...]
>>> Been there, done that, got the benefits.
>>
>> Ditto, seconded, and Aayy-men!
>
> Interaction is sometimes the hard part of testing. Method A works fine,
unless you've called Method B with value C then Method D with value E first?
Lots of things are the hard part of testing. :(
Some practitioners who have given the matter much more thought
than I ever will are scrupulous about distinguishing between "unit tests" and
"integration tests" and "system tests" (Aside: when did "acceptance tests" go
out of fashion?), but to me the demarcation lines seem not perfectly sharp. A
test for your A/B/D example might be viewed as an integration test of the A/B/D
methods, or as a unit test of the component that owns all three (does it make
the advertised state transitions in the expected way?). Deeper thinkers than I
may have a useful way to classify such things; for myself, I just try to
figure out Some Kind Of Test and let the nomenclature slide.
--
esosman@comcast-dot-net.invalid
Eleven hundred thirty-four days to go.
[toc] | [prev] | [next] | [standalone]
| From | Eric Douglas <e.d.programmer@gmail.com> (Eric Douglas) |
|---|---|
| Date | 2017-12-13 05:40 +1200 |
| Message-ID | <2142732064@f38.n261.z1.binkp.net> |
| In reply to | #37848 |
On Wednesday, December 13, 2017 at 8:21:35 AM UTC-5, Eric Sosman wrote: > Lots of things are the hard part of testing. :( > > Some practitioners who have given the matter much more thought > than I ever will are scrupulous about distinguishing between "unit > tests" and "integration tests" and "system tests" (Aside: when did > "acceptance tests" go out of fashion?), but to me the demarcation > lines seem not perfectly sharp. A test for your A/B/D example might > be viewed as an integration test of the A/B/D methods, or as a unit > test of the component that owns all three (does it make the advertised > state transitions in the expected way?). Deeper thinkers than I may > have a useful way to classify such things; for myself, I just try to > figure out Some Kind Of Test and let the nomenclature slide. > The old back end batch data processing programs were annoying enough. I once had to write a program to process gift certificate redemptions, for a corporation that owns multiple companies, so one gift certificate could be redeemed in one of the companies and may have an issuance in another company or may not find a match at all. Now I'm trying to test complex GUI controls. I wrote an extension of a JTable, so I need to make sure it works if I allow freezing x number rows, if I allow multiple row selection, if I allow sorting columns, if I allow drag and drop. Many features have an impact on the others and seem difficult if not impossible to test the combinations aside from manually generating the mouse and keyboard input. Sometimes you test every way you can think of and an end user still generates an outlier condition. I believe I have it working flawlessly right now aside from one odd "bug" I've noticed. I click on a cell to edit it and the cell editor displays a button with an image on it, works fine. I click into a different cell then use the tab key to select this cell with the button editor and the image doesn't display until I mouse over it. Why does this work differently? This is the "fun" stuff.
[toc] | [prev] | [next] | [standalone]
| From | Kiwi User <martin@mydomain.invalid> (Kiwi User) |
|---|---|
| Date | 2017-12-13 15:19 +1200 |
| Message-ID | <2563165031@f38.n261.z1.binkp.net> |
| In reply to | #37847 |
On Wed, 13 Dec 2017 04:51:52 -0800, Eric Douglas wrote:
> Interaction is sometimes the hard part of testing. Method A works fine,
> unless you've called Method B with value C then Method D with value E
> first?
My test system can handle any or all of that stuff, but doesn't even attempt to
do GUI testing because I don't have a good solution for that.
My main test harness is set up to do low level tests on a class but could be
easily extended to do more. Its main loop reads a test script, which is a text
file whose general format is
command param1 param2 param3... # comment
and, as each line is read:
- the line is printed, preceded by a line number
- comments (a '#' and everything to its right are removed
- split the remainder into 'words' on whitespace
- the first word is treated as a command, typically a method name
the other words are treated as parameters and stored as an
array of Strings and a parallel array of ints (result of
applying Integer.parseInt('word') to every parameter in the line
- call the doTest(command, p, n) method of the class-specific test
harness (see below) where p is the array of String parameters and
n is the array of int parameters,
The class specific test harness is merely a monster
if (command.equals("commandname") then
{
result = class.command(paramlist);
print("Result: " + result);
}
else
if
....
else
error("Unknown command:" + command);
structure in the doTest() method. The param list is a correctly ordered list of
specific elements in the p and n arrays.
Because the class that is the class-specific test harness contains next to
nothing apart from the if.then.else ladder, its fast and easy to write and
maintain.
Sometimes its convenient to put class-specific test helper methods in the class
specific script, but I've seldom found that to be necessary except when method
or constructor parameters are not ints or Strings.
Its constructor is passed references to print() and error() which are defined
in the test harness, so its convenient to declare all class- specific test
harnesses as subclasses of a superclass.
Common helper methods, such as one to convert T/F, Y/N, 1/0 strings into a
boolean value are defined in the superclass.
The class under test is generally created by using a command line that passes
the constructor arguments.
As I said: simple and flexible. Because each input line is listed the output
looks something like this:
1: # test10.txt - Initial test for myclass 2:
3: myclass name 23 # Create myclass with parameters "name" and 23
4:
5: #test toString
6: toString # "name is 23" expected
7: Result: name is 23
8:
9: No errors expected
No errors in test10.txt
The test harness counts calls to error() and outputs the error count at the end
of the run. I usually put the script's ID as the first line in the script and
a comment about the expected error count as the last line.
The script determines the order in which methods are executed and so its easy
to test both correct and incorrect ordering of method calls.
The output is sent to 'out', so its easy to scan through the test results,
which are generally fairly easy to read if you are careful with formatting
multiline results, i.e. indent them so they start under the first character of
the initial line and wrap overlong lines.
Regression testing is simple: just capture the results of a good test and save
it. After a regression test, compare the output with the saved results. I user
'diff' for this: a good regression test produced no output while a bad test
shows all the differences.
--
Martin | martin at
Gregorie | gregorie
| dot org
[toc] | [prev] | [next] | [standalone]
| From | Eric Douglas <e.d.programmer@gmail.com> (Eric Douglas) |
|---|---|
| Date | 2017-12-13 07:57 +1200 |
| Message-ID | <644722387@f38.n261.z1.binkp.net> |
| In reply to | #37850 |
On Wednesday, December 13, 2017 at 10:19:23 AM UTC-5, Kiwi User wrote: > > Interaction is sometimes the hard part of testing. Method A works fine, > > unless you've called Method B with value C then Method D with value E > > first? > > My test system can handle any or all of that stuff, but doesn't even > attempt to do GUI testing because I don't have a good solution for that. > > My main test harness is set up to do low level tests on a class but could > be easily extended to do more. Its main loop reads a test script, which > is a text file whose general format is > > command param1 param2 param3... # comment > I know nothing of this sort of testing though I am curious to know how you'd find the data that would generate errors when a method accepts a number and handles 1, 1.5, and 2 just fine but 1.6 returns an incorrect result. Surely GUI is worse as the human variable is bigger, and the client machine is a new variable. It may be possible to crash an API only if a user clicks too fast, or clicks on something while pressing a key at the same time, or other such unexpected activity. I had one crash we could only reproduce with a specific video driver. Sometimes the ability to crash is relative to the speed of the mouse clicking and the speed of the CPU or GPU.
[toc] | [prev] | [next] | [standalone]
| From | Kiwi User <martin@mydomain.invalid> (Kiwi User) |
|---|---|
| Date | 2017-12-13 17:30 +1200 |
| Message-ID | <280508399@f38.n261.z1.binkp.net> |
| In reply to | #37851 |
On Wed, 13 Dec 2017 07:57:40 -0800, Eric Douglas wrote:
> I know nothing of this sort of testing though I am curious to know how
> you'd find the data that would generate errors when a method accepts a
> number and handles 1, 1.5, and 2 just fine but 1.6 returns an incorrect
> result.
>
Traditionally, you'd read the design specification. The one thing you MUST NOT
do is to look at the code while you're writing tests. You're
trying to test that it does what the requirements say it should and not what
the coder wrote because he may have misunderstood the spec.
Ideally the tests would be written by somebody who wasn't involved in writing
the code and in any case NOT the code's author, but that is not always possible
and you often ending writing tests for your own code. When this happens its
always best if you can write the tests first and then code later. Next best is
if you can write the tests after you've written and compiled a skeletal class,
i.e. one with all constructors and public methods defined but with no code
inside any of them: the one exception is a compilable 'return' statement in
methods non void methods.
I usually do inductive tests, i.e. if its meant to work correctly for positive
ints over the range 1 - 999, does it work for 5,6 and 7, what about -1,0,1
(should object to -1 and 0, 1 should be OK), and do the same for 998, 999 and
1000 (first two should be OK, last flagged as out of range).
You need a set of tests that can drive the code through all its expected paths,
i.e. no errors expected and, if a method being tested is type void then you
should immediately follow its call with getters that can show that it did what
was expected. Conversely, you need to check that any method that is expected to
valid input and/or detect logic errors can successfully do so and, if error
messages are generated, that they correctly describe the error and are
understandable by whoever will be expected to read and act on them.
You'll probably get frustrated while writing the first few test sets, but once
you're up to speed with what the tests are meant to do and have developed
something of a tester's mindset it should get easier and more intuitive to do.
> Surely GUI is worse as the human variable is bigger, and the client
> machine is a new variable.
>
the major problems are how to script the various mouse clicks and keypresses
and get them into the GUI and to do the reverse process of capturing the
resulting GUI changes and saving them for automated comparisons during
regression testing.
There is already a class-level, non-GUI unit test harness, JUnit, but it wasn't
clear that it could do regression testing. I've seen it used and wasn't all
that impressed: the output looked, to me anyway, like an over bulky and
unscannable format and, as I said, it wasn't clear that it was good for
regression testing.
There may be some testing package that allows you to automate GUI tests and
regressin tests, but I haven't seen or heard of one.
> It may be possible to crash an API only if a
> user clicks too fast, or clicks on something while pressing a key at the
> same time, or other such unexpected activity. I had one crash we could
> only reproduce with a specific video driver. Sometimes the ability to
> crash is relative to the speed of the mouse clicking and the speed of
> the CPU or GPU.
>
Yes, I understand.
I tend to use the sort of scripted test harness I've described for any code
that is going to end up in a library (I use the same approach for both C and
Java) and for complex code that's nested deeply enough in an application to
make fine control of its inputs difficult.
As a compliment to the unit test harnesses that we've been talking about, I
install quite voluminous diagnostic tracing in applications and especially GUI
apps. My tracing class supports and is used to provide hierarchic tracing
levels, i.e.
Level What it shows
0 Tracing is off
1 exit from functions/methods formatted as
result = methodName(parameter values)
2 level 1 plus method entry as
methodName(parameter values) [entered]
3 anything worth tracing inside a method
My tracing system also has a circular buffering option. If this is used trace
messages are stored in a circular buffer rather then written to err and the
buffer is dumped if a fatal error (signalled by calling the diagnostic system's
error() method) which writes the buffer contents to err in arrival sequence,
outputs the error message and stops the program.
This is very useful for diagnosing randomly occurring, rare errors in long
running programs because it can show you what led up to the error exit. The
buffer size is configurable.
Since the cost, during normal live operation, of testing an integer debugging
level and then skipping over the diagnostic output is negligible in comparison
with the rest of the program's normal operations while the benefit of being
able to turn on tracing when problems occur in live code is large, I strongly
advocate using well structured diagnostics during development and leaving the
diagnostics in place whenthe code goes live.
I usually use a -d command-line option to turn debugging on. Its repeated to
get more detail, i.e. -dd for trace level 2. Buffering is typically controlled
by a -b=999 option where 999 is the buffer size in diagnostic lines stored, but
you do need a good command line parser to do this. Java didn't provide one
back in version JSE 3 days, so I wrote my own somewhat before I wrote my
diagnostic system. Both were based on stuff I'd previously written in C.
--
Martin | martin at
Gregorie | gregorie
| dot org
[toc] | [prev] | [next] | [standalone]
| From | Richard Damon <Richard@Damon-Family.org> |
|---|---|
| Date | 2017-12-15 22:31 -0500 |
| Message-ID | <Ps0ZB.402$yr3.305@fx13.iad> |
| In reply to | #37852 |
On 12/13/17 12:30 AM, Kiwi User (Kiwi User) wrote: >> I know nothing of this sort of testing though I am curious to know how >> you'd find the data that would generate errors when a method accepts a >> number and handles 1, 1.5, and 2 just fine but 1.6 returns an incorrect >> result. >> > Traditionally, you'd read the design specification. The one thing you MUST NOT > do is to look at the code while you're writing tests. You're > trying to test that it does what the requirements say it should and not what > the coder wrote because he may have misunderstood the spec. One major exception to this, is that the people who write the code should report to the testers any algorithmic breakpoints that are not implied by the specifications. For instance, the size of the data being processed my affect which method is used to reach the goal. The test suite needs to make sure it exercises every case. Testing likely would test the smallest and largest, but if there is distinct middle case, it might be missed, and tests near the break points might be called for too.
[toc] | [prev] | [next] | [standalone]
| From | Kiwi User <martin@mydomain.invalid> |
|---|---|
| Date | 2017-12-16 09:08 +0000 |
| Message-ID | <p12nqd$ro3$1@news.albasani.net> |
| In reply to | #37853 |
On Fri, 15 Dec 2017 22:31:59 -0500, Richard Damon wrote:
> On 12/13/17 12:30 AM, Kiwi User (Kiwi User) wrote:
>>> I know nothing of this sort of testing though I am curious to know how
>>> you'd find the data that would generate errors when a method accepts a
>>> number and handles 1, 1.5, and 2 just fine but 1.6 returns an
>>> incorrect result.
>>>
>> Traditionally, you'd read the design specification. The one thing you
>> MUST NOT do is to look at the code while you're writing tests. You're
>> trying to test that it does what the requirements say it should and not
>> what the coder wrote because he may have misunderstood the spec.
>
I should have extended this to say that testers should read javadocs
output but not the actual source code.
> One major exception to this, is that the people who write the code
> should report to the testers any algorithmic breakpoints that are not
> implied by the specifications.
>
There's a bit more they should do as well: this needs to be reflected
back to the designers and added into the system documentation. It also
needs to be clearly documented in the code, e.g. in Java it needs to be
mentioned in class and/or method-level comments so that it is visible in
javadocs output.
> For instance, the size of the data being
> processed my affect which method is used to reach the goal. The test
> suite needs to make sure it exercises every case. Testing likely would
> test the smallest and largest, but if there is distinct middle case, it
> might be missed, and tests near the break points might be called for
> too.
IOW prefer to see this sort of thing described at both the documentation
that designers working on system changes and enhancements will read *and*
where it should be seen and read by devs making changes to the code.
--
Martin | martin at
Gregorie | gregorie
| dot org
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.java.programmer
csiph-web