Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.java.programmer > #37813 > unrolled thread
| Started by | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| First post | 2017-12-12 08:09 -0800 |
| Last post | 2017-12-13 17:30 +0000 |
| Articles | 15 — 3 participants |
Back to article view | Back to comp.lang.java.programmer
Calling deprecated methods Eric Douglas <e.d.programmer@gmail.com> - 2017-12-12 08:09 -0800
Re: Calling deprecated methods Kiwi User <martin@mydomain.invalid> - 2017-12-12 16:31 +0000
Re: Calling deprecated methods Eric Douglas <e.d.programmer@gmail.com> - 2017-12-12 10:24 -0800
Re: Calling deprecated methods Kiwi User <martin@mydomain.invalid> - 2017-12-12 20:05 +0000
Re: Calling deprecated methods Eric Sosman <esosman@comcast-dot-net.invalid> - 2017-12-12 15:41 -0500
Re: Calling deprecated methods Kiwi User <martin@mydomain.invalid> - 2017-12-12 21:04 +0000
Re: Calling deprecated methods Eric Douglas <e.d.programmer@gmail.com> - 2017-12-12 13:33 -0800
Re: Calling deprecated methods Kiwi User <martin@mydomain.invalid> - 2017-12-12 22:41 +0000
Re: Calling deprecated methods Eric Sosman <esosman@comcast-dot-net.invalid> - 2017-12-12 17:57 -0500
Re: Calling deprecated methods Eric Douglas <e.d.programmer@gmail.com> - 2017-12-13 04:51 -0800
Re: Calling deprecated methods Eric Sosman <esosman@comcast-dot-net.invalid> - 2017-12-13 08:21 -0500
Re: Calling deprecated methods Eric Douglas <e.d.programmer@gmail.com> - 2017-12-13 05:40 -0800
Re: Calling deprecated methods Kiwi User <martin@mydomain.invalid> - 2017-12-13 15:19 +0000
Re: Calling deprecated methods Eric Douglas <e.d.programmer@gmail.com> - 2017-12-13 07:57 -0800
Re: Calling deprecated methods Kiwi User <martin@mydomain.invalid> - 2017-12-13 17:30 +0000
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2017-12-12 08:09 -0800 |
| Subject | Calling deprecated methods |
| Message-ID | <b1215ae8-2a70-4220-b98a-6d25088c5ae6@googlegroups.com> |
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? 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? For some reason Java 9 MouseEvent deprecated getModifiers(), but JTree still looks for that value.
[toc] | [next] | [standalone]
| From | Kiwi User <martin@mydomain.invalid> |
|---|---|
| Date | 2017-12-12 16:31 +0000 |
| Message-ID | <p0p09n$fed$1@news.albasani.net> |
| In reply to | #37813 |
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] | [prev] | [next] | [standalone]
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2017-12-12 10:24 -0800 |
| Message-ID | <9db47be9-1c38-48a9-bad9-9799f54df59a@googlegroups.com> |
| In reply to | #37814 |
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> |
|---|---|
| Date | 2017-12-12 20:05 +0000 |
| Message-ID | <p0pcpd$j65$1@news.albasani.net> |
| In reply to | #37815 |
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> |
|---|---|
| Date | 2017-12-12 15:41 -0500 |
| Message-ID | <p0peu7$cd4$1@dont-email.me> |
| In reply to | #37817 |
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> |
|---|---|
| Date | 2017-12-12 21:04 +0000 |
| Message-ID | <p0pg91$b3f$1@news.albasani.net> |
| In reply to | #37818 |
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> |
|---|---|
| Date | 2017-12-12 13:33 -0800 |
| Message-ID | <c0757a6b-fed6-4ee8-b75d-e6b220bfa894@googlegroups.com> |
| In reply to | #37819 |
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> |
|---|---|
| Date | 2017-12-12 22:41 +0000 |
| Message-ID | <p0plu3$tqm$1@news.albasani.net> |
| In reply to | #37827 |
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> |
|---|---|
| Date | 2017-12-12 17:57 -0500 |
| Message-ID | <p0pms6$4o2$1@dont-email.me> |
| In reply to | #37830 |
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> |
|---|---|
| Date | 2017-12-13 04:51 -0800 |
| Message-ID | <6538543c-98d3-460d-bca1-185227ab9a84@googlegroups.com> |
| In reply to | #37831 |
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> |
|---|---|
| Date | 2017-12-13 08:21 -0500 |
| Message-ID | <p0r9ga$ikh$1@dont-email.me> |
| In reply to | #37832 |
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> |
|---|---|
| Date | 2017-12-13 05:40 -0800 |
| Message-ID | <2bf1baf9-36e6-45c0-afb2-473716224fdc@googlegroups.com> |
| In reply to | #37833 |
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> |
|---|---|
| Date | 2017-12-13 15:19 +0000 |
| Message-ID | <p0rgd5$4t7$1@news.albasani.net> |
| In reply to | #37832 |
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> |
|---|---|
| Date | 2017-12-13 07:57 -0800 |
| Message-ID | <c3fa867e-51a3-4bdf-8499-0a74c6a194b0@googlegroups.com> |
| In reply to | #37835 |
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> |
|---|---|
| Date | 2017-12-13 17:30 +0000 |
| Message-ID | <p0ro43$i80$1@news.albasani.net> |
| In reply to | #37836 |
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] | [standalone]
Back to top | Article view | comp.lang.java.programmer
csiph-web