News for hackers. Stuff that matters.
Re:Automated Unit Test Improvement Using Large Language Mode... by hubraumhugo on Saturday February 17, 2024 @02:07AM (#39407128)
At a large insurance company I worked for, management set a target of 80% test coverage across our entire codebase. So people started writing stupid unit tests for getters and setters in Java DTOs to reach the goal. Of course devs also weren't allowed to change the coverage measuring rules in Sonar.

As a young dev, it taught me that focusing only on KPIs can sometimes drive behaviors that don't align with the intended goals. A few well-thought out E2E test scenarios would probably have had a better impact on the software quality.

Re:Automated Unit Test Improvement Using Large Language Mode... by wilgertvelinga on Saturday February 17, 2024 @03:27AM (#39407557)
The solution to that is mutation tests. They force your tests to actually verify the implementation instead of just running the code to fake coverage. https://en.m.wikipedia.org/wiki/Mutation_testing Tools and frameworks exist for almost all languages. Some examples:

- stryker-mutator (C#, Typescript)

- pitest (Java)

- mutatest (Python)

Re:Automated Unit Test Improvement Using Large Language Mode... by misja111 on Saturday February 17, 2024 @04:21AM (#39407828)
I have tried those out for a large Java project. The problem is that it is just too slow to use with a large unit test suite. What mutation testing does, is running all the tests in your suite multiple times while changing some of your code base ("mutation points") to see if it affects the test outcome (it should). So say that your test suite normally takes 10 minutes, then a full mutation suite can easily be a factor 50 slower, which means 8 hours.
Re:Automated Unit Test Improvement Using Large Language Mode... by jononor on Saturday February 17, 2024 @04:29AM (#39407863)
Perfect for a daily CI job?
Re:Automated Unit Test Improvement Using Large Language Mode... by polynomial on Saturday February 17, 2024 @10:09AM (#39410086)
"daily CI"?
Re:Automated Unit Test Improvement Using Large Language Mode... by rafaelmn on Saturday February 17, 2024 @01:03PM (#39411753)
People tend to use CI as a synonym for automated build pipeline.
Re:Automated Unit Test Improvement Using Large Language Mode... by polynomial on Thursday February 22, 2024 @12:59AM (#39463702)
So I've heard
Re:Automated Unit Test Improvement Using Large Language Mode... by wilgertvelinga on Saturday February 17, 2024 @06:28AM (#39408509)
Find ways to reduce those 10 minutes. Some ideas: - make the individual tests run faster - remove obsolete tests - increase parallellism - use a tool that can determine which tests to run based on what has changed, for example nx.dev.
Re:Automated Unit Test Improvement Using Large Language Mode... by LadyCailin on Saturday February 17, 2024 @07:31AM (#39408863)
You don’t block on that, you run it on a continuous loop in a CI. Then, if tests fail, you are limited to the checkins over the last day or whatever, and you can more easily bisect to find the offending PR, and file a bug against that dev to fix, or just revert the change. But you dont run the full suite locally, though there are ways for stryker anyways to only test code that changed, which you can run locally, or in the PR build.
Re:Automated Unit Test Improvement Using Large Language Mode... by MichaelNolan on Saturday February 17, 2024 @05:03AM (#39408064)
Mutation testing is really amazing for some types of code. And it definitely solves the problem of “fake unit tests”. Though sometimes it does force the tests to be a little too tightly coupled with the code. (Though that usually indicates that the code could be refactored)
Re:Automated Unit Test Improvement Using Large Language Mode... by nprateem on Saturday February 17, 2024 @05:48AM (#39408305)
Or instead of adding more rules and tech solutions, discuss with the team and gain buy-in on code quality and processes.
Re:Automated Unit Test Improvement Using Large Language Mode... by pawelduda on Saturday February 17, 2024 @11:05AM (#39410662)
Also mutant (ruby). Good but unfortunately with costly subscription for commercial use
Re:Automated Unit Test Improvement Using Large Language Mode... by DylanSp on Wednesday February 21, 2024 @03:24PM (#39459003)
The paper in the OP mentions mutation testing at the end when talking about future work and open problems (section 7). They think it'd be very useful, but it's "challenging to deploy such computationally demanding techniques at the scale we would require".
Re:Automated Unit Test Improvement Using Large Language Mode... by supriyo-biswas on Saturday February 17, 2024 @02:26AM (#39407236)
Re:Automated Unit Test Improvement Using Large Language Mode... by hubraumhugo on Saturday February 17, 2024 @02:36AM (#39407277)
Thanks, I was looking for that name.

Interesting examples:

> San Francisco Declaration on Research Assessment – 2012 manifesto against using the journal impact factor to assess a scientist's work. The statement denounces several problems in science and as Goodhart's law explains, one of them is that measurement has become a target. The correlation between h-index and scientific awards is decreasing since widespread usage of h-index.

> International Union for Conservation of Nature's measure of extinction can be used to remove environmental protections, which resulted in IUCN becoming more conservative in labeling something as extinct

Re:Automated Unit Test Improvement Using Large Language Mode... by danielheath on Saturday February 17, 2024 @02:45AM (#39407321)
IME, the only "test coverage % rule" that I've ever seen work was "must not decrease the overall percentage of tested code". Once you get to 100%, that becomes "All code must have a test".

Various people objected to this, pointing out that 100% test coverage tells you nothing about whether the tests are any good. Our lead (wisely, IMO) responded that they were correct - 100% tells you nothing - but that _any other percentage_ does tell you something.

Re:Automated Unit Test Improvement Using Large Language Mode... by vasco on Saturday February 17, 2024 @03:22AM (#39407536)
What tells you something is how many releases get rolled back as a % and how much rework you have. If your developers need 3 attempts to put something working in production that's all you need to know about the quality of the reviews and tests. High or low coverage, what you need to look at is actual issues.

All you need is a bit hyperbolic, because you also need to quarantine flaky tests and other things, but coverage as a whole I think is useful only if you have an engineering organization that doesn't see the point in tests - but that's going to be an uphill battle.

Re:Automated Unit Test Improvement Using Large Language Mode... by polynomial on Saturday February 17, 2024 @10:26AM (#39410280)
Good heavens, a team needing 3 tries to get something into production sounds like they need a QA refresher.
Re:Automated Unit Test Improvement Using Large Language Mode... by withinboredom on Saturday February 17, 2024 @10:50AM (#39410536)
Most of the time, I see teams mixing refactoring, bug fixing, and new features into a single PR which causes this. Keeping PRs focused makes it easier to review and find issues before shipping to prod.

In other words, first bug-fix PR should be hacky af to fix the bug. No refactoring, nothing controversial (other than the hacky af fix). After you verify the fix in production, then, and only then, do you open a PR to refactor the code. Finally, after that is verified in production, close the bug ticket.

Re:Automated Unit Test Improvement Using Large Language Mode... by sdiupIGPWEfh on Sunday February 18, 2024 @06:25PM (#39424604)
I loved having small, focused PRs. So much easier to review without interrupting my day, too. Then we got handed a policy of one PR per ticket to simplify our QA process. Oh well.
Re:Automated Unit Test Improvement Using Large Language Mode... by nimblegorilla on Saturday February 17, 2024 @11:36AM (#39410967)
> Coverage as a whole I think is useful only if you have an engineering organization that doesn't see the point in tests - which is going to be its own uphill battle.

I think coverage stats are always useful as they help find the edge cases that people forgot to test. A common culprit I've seen is error handling code where a bunch of tests target the happy path, but nothing tests the error logging when something breaks.

Re:Automated Unit Test Improvement Using Large Language Mode... by ponector on Saturday February 17, 2024 @03:48AM (#39407659)
I had a colleague who wrote unit tests without any assertions. Perfect idea! 100% coverage and always green.

Another comment here mentioned mutation tests which could be a solution to increase quality of unit testing, but I've never seen anyone to actually use it in enterprise development. Same story with test driven development concept.

Re:Automated Unit Test Improvement Using Large Language Mode... by srvaroa on Saturday February 17, 2024 @04:08AM (#39407773)
I hear this point as a counter argument to “never decrease coverage helps maintain quality”.

It is technically correct. But, it is only meaningful if you assume a bad actor in the team who knowingly games the system, and a team who tolerates it.

At that point, your problem has nothing to to with code quality, nor is coverage meant to be a solution for it.

Re:Automated Unit Test Improvement Using Large Language Mode... by zarathustreal on Saturday February 17, 2024 @04:58AM (#39408039)
You're missing the point entirely. This point is a counter example to the implied assertion that some percentage of code coverage indicates correctness. That alone is enough to prove that the implication is false.

That being said, you don't need to assume a bad actor in the team to encounter the situation of having 100% code coverage with meaningless tests. Even the most well-meaning engineer can accidentally write tests that boil down to asserting "true == true" without proving anything about the code paths it touches. This isn't necessarily a cultural issue.

I'd even assert that, due to the languages in common use, it's very common to see these sort of "touch all the code paths but assert nothing about the correctness of the code" tests. Standard OOP languages like TypeScript or Java for example have relatively limited type systems and allow mutable variables, so you end up with implementations of algorithms and data structures that don't lend themselves to property-based testing. This leads to tests which basically just duplicate the implementation and assert "I wrote what I wrote" or in other words "true == true".

Re:Automated Unit Test Improvement Using Large Language Mode... by srvaroa on Saturday February 17, 2024 @06:20AM (#39408461)
> You don't need to assume a bad actor in the team to encounter the situation of having 100% code coverage with meaningless tests.

Indeed. The thing is, I was replying to a comment that referred _explicitly_ to a bad actor. The situation @ponector describes (team's coverage indicator is rendered useless because have a bad actor games it), THEN the cause is not coverage. It says nothing about coverage beyond "a tool only works in certain conditions".

You bring 2 more cases that break the indicator, and I agree with both (there are more!). We have (1): We all make mistakes and write dumb tests. (2): Coverage is not useful for _some_ practises / scopes of testing.

I agree on both. But we're back on the same place. I'm not saying those problems don't exist. I'm saying that those are not problems coverage ever claimed to solve. Making a sweeping dismissal of a tool because it doesn't solve problems it never claimed to solve is throwing away the baby with the dirty water.

* Coverage does not claim to be a tool to fix bad actor, (1) or (2)! There are other tools to cover those risks (e.g. managers, code reviews, pair programming, etc.).

* Discussions about those tools (code reviews, etc.) tend to make the same mistake. Find problems the tool doesn't claim to solve to dismiss the tool.

* This all happens because people pretend to treat tools like coverage, tests, DORA metrics, as silver bullets. They are not. They are all meant to be a toolbox that engineers evaluate and use where they yield value.

And this is why yes, a lot of the "$tool is useless because $situation_where_it_doesnt_work" conversations are fundamentally about cultural issues. If your team uses a tool without knowing what problem is trying to solve, you have a cultural issue. If your tool has an actual purpose, and yet engineers are intentionally working around it, you have a cultural issue. Etc.

Re:Automated Unit Test Improvement Using Large Language Mode... by cma on Saturday February 17, 2024 @12:32PM (#39411436)
There is no such implied assertion, he said:

> 100% tells you nothing - but that _any other percentage_ does tell you something.

100% doesn't tell you it is meaningful coverage, but less than 100% tells you for sure that uncovered part doesn't have meaningful coverage.

Re:Automated Unit Test Improvement Using Large Language Mode... by foota on Saturday February 17, 2024 @04:11AM (#39407787)
Mutation testing is enabled at at least some of the large tech companies, though I don't know how widely.
Re:Automated Unit Test Improvement Using Large Language Mode... by bgribble on Saturday February 17, 2024 @08:53AM (#39409408)
I'm not saying this is a good practice, but it's not valueless. Exceptions are failures. If you have code that is straight broken -- refers to an undefined variable, assumes something that's not true, syntax error that could make it past initial app load -- a test that at least makes sure the code is runnable without throwing an error is better than nothing.
Re:Automated Unit Test Improvement Using Large Language Mode... by Ygg2 on Saturday February 17, 2024 @04:39AM (#39407921)
>Once you get to 100%

Once you get there you already fucked up. In Java covering 100% lines means in average case testing Lombok and every equals hash. If you're doing that you fucked up.

Re:Automated Unit Test Improvement Using Large Language Mode... by groestl on Saturday February 17, 2024 @05:11AM (#39408111)
I've seen broken hash implementations many times, so I'm not sure it would be a bad idea to require tests for them ;)

My other favourite of trivial code that's broken: returning the same Iterator instance in Iterable.iterator()

Re:Automated Unit Test Improvement Using Large Language Mode... by Ygg2 on Saturday February 17, 2024 @01:57PM (#39412295)
Broken or just working with Hibernate?

I remember hibernate recommending using static hash. In order to prevent saving entities changing hash values.

Re:Automated Unit Test Improvement Using Large Language Mode... by strken on Saturday February 17, 2024 @04:56AM (#39408026)
This works better as "All tests decreasing the overall percentage of tested code must have a good explanation signed off on by the reviewer". I've occasionally deleted dead code paths, had an almost entirely red diff, had close to 100% test coverage over the functions I touched, and yet decreased the overall percentage of tested code because the dead code path was more heavily tested than the rest of the code base.
Re:Automated Unit Test Improvement Using Large Language Mode... by stavros on Saturday February 17, 2024 @10:52AM (#39410554)
I kind of disagree, in that any rule should have an implied "you can ignore this with good justification". Otherwise you turn people into robots, which renders moot all the reasons why you have people, and not robots.
Re:Automated Unit Test Improvement Using Large Language Mode... by strken on Saturday February 17, 2024 @04:15PM (#39413628)
I agree with this - in practice any rule can be broken - but how easily it's broken and whether developers are explicitly told to break it is a process decision. How big a roadblock is your CI putting in the path of developers? If you require e.g. sign-off from a team lead or manager or whoever has "merge anyway" permissions in GitHub, that's more difficult than sign-off from the same reviewer who's reading your code anyway. You can make it easier or harder to break rules and in this case I think it should be so easy to break that there's a codified procedure to do so.
Re:Automated Unit Test Improvement Using Large Language Mode... by danielheath on Saturday February 17, 2024 @05:25PM (#39414110)
I haven’t tried that - in that situation we did “find something that needs a test”
Re:Automated Unit Test Improvement Using Large Language Mode... by berkes on Saturday February 17, 2024 @05:22AM (#39408166)
I like that.

What I also do, is ensure test coverage is over 100%¹ for important parts. Important is designated through churn (if a file or class os changed on every second commit, it must be important) and through domain knowledge (building a recipe app, then likely the Recipe is important).

¹ covered by unit tests, AND (partially) covered by integration AND by E2E tests.

Re:Automated Unit Test Improvement Using Large Language Mode... by nonethewiser on Saturday February 17, 2024 @08:23AM (#39409193)
> IME, the only "test coverage % rule" that I've ever seen work was "must not decrease the overall percentage of tested code".

That’s a stupid rule and not measuring what you think it is.

It fails if you just delete tested code.

It fails if you remove some code thats tested and add some tested code, but not enough.

These are all extremely common for any refactor. Here is a simplistic example but imagine the same principles applied to a large set of changes. Dozens of files, thousands of lines. You cant just manually account for that.

50%: 100 lines of code. 50 covered, 50 uncovered.

remove some function and its 44% from 40 covered, 50 uncovered. Failed.

Or remove some function and replace it with something better thats not as long. 44 covered, 50 uncovered. 47% coverage. Failed.

A stack overflow post about this.

https://softwareengineering.stackexchange.com/questions/4007...

This inevitably leads to worthless tests to increase coverage and avoiding optionL refactors.

Re:Automated Unit Test Improvement Using Large Language Mode... by angra_mainyu on Saturday February 17, 2024 @09:11AM (#39409547)
It sounds great but I beg to differ.

If I had to pick one rule that is great to always follow, is when you get hit with a bug, write tests that catch it and then write code to fix the test.

Aside from preventing said bugs from resurfacing, it forces coverage of code that is likely complex enough to be buggy.

Re:Automated Unit Test Improvement Using Large Language Mode... by Fargren on Saturday February 17, 2024 @09:11AM (#39409551)
> "must not decrease the overall percentage of tested code"

This rule has been a problem for me when deleting code. On my precious check we had an automated checker that wouldn't let us merge (easily) if we broke this rule. We had mediocre coverage. Some parts of the code had lots of tests, some parts were totally uncovered. Many times I had to delete code in the tested parts, and the checker would complain that total coverage went down because I deleted a tested line without adding more tested lines.

But I agree it's a good rule in general, which is why we kept it despite the occasional hiccup.

Re:Automated Unit Test Improvement Using Large Language Mode... by pfdietz on Saturday February 17, 2024 @11:24AM (#39410847)
I'd worry about test coverage as soon as the team commits to actually fixing every bug found.
Re:Automated Unit Test Improvement Using Large Language Mode... by oneshtein on Saturday February 17, 2024 @02:32AM (#39407254)
Is it hard to write ONE test case for ALL getters and setters using reflection?
Re:Automated Unit Test Improvement Using Large Language Mode... by reactordev on Saturday February 17, 2024 @02:37AM (#39407280)
at that point what are you testing? allocation/deallocation? Nothing is actually happening unless you depend on constructors/destructors when you use reflection to gen a mock type or real value type to inject. Or do you mean just assert true that all getters are not null?

I agree that unit testing for the sake of KPI's is the wrong approach and unit testing functionality (as a means of documenting it, proving it still works as intended) is far better.

Re:Automated Unit Test Improvement Using Large Language Mode... by oneshtein on Saturday February 17, 2024 @03:35AM (#39407593)
> at that point what are you testing?

Memory.

> Nothing is actually happening unless you depend on constructors/destructors when you use reflection to gen a mock type or real value type to inject.

Just get an object from IoC container, then test that getFoo() == getFoo(setFoo(getFoo())) for every Foo with get and set methods, so you will have 80% of coverage for those getters and setters. For read-only properties, just get value and throw it away.

> I agree that unit testing for the sake of KPI's is the wrong approach and unit testing functionality (as a means of documenting it, proving it still works as intended) is far better.

Unit tests are for proving correctness of logic in a unit of code. Data structures are not logic. IMHO, such trivial parts of program should be ignored by coverage tool, but topic starter said that they cannot change rules. :-/

Re:Automated Unit Test Improvement Using Large Language Mode... by growse on Saturday February 17, 2024 @03:52AM (#39407680)
> > at that point what are you testing?

> Memory.

In unit testing, the "memory" is not the system under test though.

Re:Automated Unit Test Improvement Using Large Language Mode... by zarathustreal on Saturday February 17, 2024 @05:08AM (#39408098)
>> at that point what are you testing? > Memory.

It doesn't make sense to test something you have no control over, if the OS fails to allocate memory there's nothing you can change in your code to fix that.

Likewise, if you're improperly instructing the OS to allocate memory (via some constructor or factory or whatever) there is no test you can write to test your own intentions that won't be subject to exactly the same level of incorrectness as the implementation code itself. If you've written "do the thing" writing a "test" that says "hey make sure I wrote 'do the thing'" is ridiculous.

I've often found this to be a matter of semantics. Someone will say they're writing a "unit test" and load all the assertions and logic associated with the meaning of "unit test" into their brain and then try to apply it in a way that subtly invalidates those assertions when they start writing.

To make things worse, there's a cultural disinclination toward "semantic arguments" so you end up arguing with people that have basically no chance of understanding why what they're doing doesn't provide the value it should

Re:Automated Unit Test Improvement Using Large Language Mode... by Mawr on Saturday February 17, 2024 @05:11AM (#39408116)
You shouldn't have setters in the first place. What's the point of encapsulation if anyone can just set properties at will?
Re:Automated Unit Test Improvement Using Large Language Mode... by noisy_boy on Saturday February 17, 2024 @07:51AM (#39408999)
Sometimes the value you pass to a setter can go through additional logic to determine the final value to be set e.g.:

    private int value1;

    private int value2;

    public void setValue2(int value2) {
        this.value2 = value2;                  
    }
    
    public void setValue1(int value1) {
        if (this.value2 > 0) {
            this.value1 = value1 + this.value2;
        } else {
            this.value1 = value1;
        }
    }

Obviously this is a contrived example but if you have logic other than a simple "this.value = value", then you might want to unit test that bit.
Re:Automated Unit Test Improvement Using Large Language Mode... by tom_ on Saturday February 17, 2024 @09:59AM (#39410005)
Also useful if you want to add logging, or capture some metrics, or set a breakpoint.
Re:Automated Unit Test Improvement Using Large Language Mode... by growse on Saturday February 17, 2024 @12:28PM (#39411405)
Ah, the sound of people not using their type system properly.

Parse, don't validate.

Re:Automated Unit Test Improvement Using Large Language Mode... by reactordev on Saturday February 17, 2024 @12:42PM (#39411550)
But also don’t create AggregateNonNegativeInteger type when generics will do.
Re:Automated Unit Test Improvement Using Large Language Mode... by ildjarn on Saturday February 17, 2024 @02:41AM (#39407304)
Simplest solution? Don’t have any setters.
Re:Automated Unit Test Improvement Using Large Language Mode... by thomasahle on Saturday February 17, 2024 @02:57AM (#39407406)
Removing them would reduce your coverage percentage.
Re:Automated Unit Test Improvement Using Large Language Mode... by srvaroa on Saturday February 17, 2024 @04:12AM (#39407794)
Good thing. It shows that a % of your tests were actually not targeted at the most important areas of the code base
Re:Automated Unit Test Improvement Using Large Language Mode... by tauwauwau on Saturday February 17, 2024 @05:47AM (#39408297)
I had to do it in one project. It's not trivial, but also not too difficult. Getters were easy, setters required different types of values. After handling various date type values for setters it worked fine. Occasionally I would see an exception for fields generated by APIs like Lombok, which needed to be excluded from my setter list.

I didn't like that I had tobdo it, but it was easier than getting several approvals to get Sonar rules changed.

Re:Automated Unit Test Improvement Using Large Language Mode... by jghn on Saturday February 17, 2024 @08:07AM (#39409086)
Or stop using the broken pattern of getters and setters
Re:Automated Unit Test Improvement Using Large Language Mode... by geraldwhen on Saturday February 17, 2024 @08:19AM (#39409167)
I ask interview candidates to explain why they’re using getters or setters. They never have a reason.
Re:Automated Unit Test Improvement Using Large Language Mode... by danielovichdk on Saturday February 17, 2024 @11:36AM (#39410970)
Let's say you have a type. Let's call it List.

When you create a List you want to enable the possibility of setting a Capacity - how large can this List be.

And you also want to enable reading how large the List is at a given point.

Pretty valid case for a setter and a getter in my book.

Re:Automated Unit Test Improvement Using Large Language Mode... by drowsspa on Saturday February 17, 2024 @09:35AM (#39409752)
Would "because it's conventional and most tools and developers assume them" be an acceptable answer? The reason I read is "because you might wanna change the implementation" but honestly it's seems very rare to need to do that
Re:Automated Unit Test Improvement Using Large Language Mode... by BlackFly on Saturday February 17, 2024 @10:28AM (#39410300)
Because your data structure and your API are separate things and generally speaking, the data structure should be opaque to users of that structure unless it's sole purpose is as a record for a bunch of request arguments. For those fat request structures, it ends up being a lot of noise indeed, but in any case most of those structures for most people are dealt with by deserialization and you can often skip generation of setters and getters or autogenerate them.

Do you want to return a copy/clone of the inner object or just let people mutate it, destroying all of your data structure's invariants? Yes, if you change the implementation of the structure, user code will also break and it is certainly easier to do that behind a method, this is indeed rare in practice but the nuisance of migrating direct access to indirect access is bigger than the nuisance of (today's) unnecessary indirection.

Since in some cases safety around invariants and future proofing will require the level of indirection, it is easier to just expect the convention. Moreover, codegen can just produce them for you, they can be excluded from test coverage. Then there are languages like python that allow you in the future to pretend that indirect access is direct access and cannot protect invariants in any case, so just go direct from day one.

Re:Automated Unit Test Improvement Using Large Language Mode... by drowsspa on Saturday February 17, 2024 @11:21AM (#39410811)
Yeah, that's the textbook explanation, I guess. So I'll stick to it in interviews, as useless it is in real life.

All the hoops for this... Codegen, excluding from coverage, Lombok, and all that magic to hide you from a simple obj.field that is all you're doing in 99.9% of cases. It's just so rare in practice. I think the language itself should allow for readonly fields and property setters for the extremely rare occasions where you need this.

Re:Automated Unit Test Improvement Using Large Language Mode... by xxs on Saturday February 17, 2024 @12:37PM (#39411496)
The correct solution is not having either. Getter/setters are effectively an anti pattern as they support needless mutability but worse they add nothing of value.

As a general rule most fields should be initialized in the c-tor, and they should be final.

Re:Automated Unit Test Improvement Using Large Language Mode... by dexwiz on Saturday February 17, 2024 @02:51AM (#39407371)
I’ve started getting pinged for this at my current job. I think it’s time to move on.
Re:Automated Unit Test Improvement Using Large Language Mode... by farhanhubble on Saturday February 17, 2024 @02:14AM (#39407159)
True of any metric when it becomes the goal in itself.
Re:Automated Unit Test Improvement Using Large Language Mode... by raverbashing on Saturday February 17, 2024 @02:42AM (#39407308)
Java is the only place where (non-automatic/non-syntax-sugared) getters and setters are though as important and valuable

Only goes to confirm my view of them that the language is deficient

Re:Automated Unit Test Improvement Using Large Language Mode... by CraigJPerry on Saturday February 17, 2024 @03:41AM (#39407625)
I don’t think it’s accurate to label that as a language problem.

That is very squarely a people problem.

It’s not as bad today - many Java juniors don’t have the “bean” affliction burned into their brains so they don’t object to public fields on data carriers (today you’d just use a record) but even the bean generation (mostly people my age) can usually be won over these days by negotiating with them on cases where getters/setters can be eliminated (e.g. start with value objects, then suggest maybe DTOs then you can go for the kill - why do we need the stupid Java bean convention?)

Re:Automated Unit Test Improvement Using Large Language Mode... by hubraumhugo on Saturday February 17, 2024 @02:43AM (#39407313)
Record types solved this in JDK 14
Re:Automated Unit Test Improvement Using Large Language Mode... by groestl on Saturday February 17, 2024 @05:12AM (#39408122)
I mean public final was there before as well.
Re:Automated Unit Test Improvement Using Large Language Mode... by drowsspa on Saturday February 17, 2024 @09:36AM (#39409760)
Cries in Java 8
Re:Automated Unit Test Improvement Using Large Language Mode... by Slartie on Saturday February 17, 2024 @05:22AM (#39408167)
Modern Java projects either use records, org.immutables or Lombok. Manual getter/setter creation is the exception nowadays.
Re:Automated Unit Test Improvement Using Large Language Mode... by srvaroa on Saturday February 17, 2024 @08:17AM (#39409158)
I don’t find they are valued like that. IME most devs who use them perceive them as annoying boilerplate. Proof being how Lombok or Records are generally well received among the younger gen.

The problem on this topic is that they cargo cult getters/setters by inertia, usually because more experienced engs pass it on as good practice.

It’s not an inherent problem to the language.

Re:Automated Unit Test Improvement Using Large Language Mode... by dclowd9901 on Saturday February 17, 2024 @02:42AM (#39407309)
What if…

They knew that people would write coverage tests for getters and setters, and calculated that eventuality into their minimums.

Re:Automated Unit Test Improvement Using Large Language Mode... by mrich on Saturday February 17, 2024 @02:48AM (#39407351)
So you're saying they knew engineers would be wasting their time doing useless things, but still went ahead? (instead of mandating 75% and spending 1/100 of the wasted time to adjust the metric to filter out getter/setter)
Re:Automated Unit Test Improvement Using Large Language Mode... by dev_tty01 on Saturday February 17, 2024 @09:36AM (#39409755)
I just assumed they wrote a script to automatically generate all the setter/getter tests and then took a long lunch.
Re:Automated Unit Test Improvement Using Large Language Mode... by Galanwe on Saturday February 17, 2024 @04:30AM (#39407878)
I can relate. At my first internship, there was a code quality tool forced on the team by management as well. It had a rule to "disable magic numbers".

The result was a header with:

    static const unsigned ONE = 1;
    static const unsigned TWO = 2;
    static const unsigned THREE = 3;
   ... 
Up to some thousands.
Re:Automated Unit Test Improvement Using Large Language Mode... by isoprophlex on Saturday February 17, 2024 @06:48AM (#39408612)
Heavens forbid you want to raise some number to the power of 2, err I mean TWO
Re:Automated Unit Test Improvement Using Large Language Mode... by awestroke on Saturday February 17, 2024 @07:07AM (#39408719)
Really? You could not come up with a way to avoid magic numbers?
Re:Automated Unit Test Improvement Using Large Language Mode... by GuB-42 on Saturday February 17, 2024 @07:48AM (#39408972)
Sometimes, a number is just a number. The average of a, b, c is (a+b+c)/3, an positive interger is single digit when less then 10, the formula for the volume of a sphere is 4/3PIr^3, etc... And that's excluding 0, 1 and 2 which are naturally everywhere.

That some numbers are not magic would be obvious to a human reviewer, but the tool probably just treats any number in an expression as a magic number or something like that, and the workaround is to define constants for raw numbers. Which entirely defeats the purpose since now, people will just use these constants for actual magic numbers and the tool will see nothing.

Re:Automated Unit Test Improvement Using Large Language Mode... by jader201 on Saturday February 17, 2024 @08:30AM (#39409234)
Maybe in rare cases, but in my experience, literals (numbers or strings) almost always have _some_ meaning where giving them a name helps readability. In my experience, it’s rare that “a number is just a number”. And sure, in those cases, naming them is silly.
Re:Automated Unit Test Improvement Using Large Language Mode... by aqme28 on Saturday February 17, 2024 @08:35AM (#39409268)
Listen, what happens if we want to calculate delivery distances in a n-dimensional universe?
Re:Automated Unit Test Improvement Using Large Language Mode... by 542458 on Saturday February 17, 2024 @08:36AM (#39409277)
That 3 in your first example is definitely a magic number that should be either dynamically calculated from the number of elements being averaged, or defined as a const NUMBER_ELEMENTS_AVERAGED.
Re:Automated Unit Test Improvement Using Large Language Mode... by GuB-42 on Saturday February 17, 2024 @10:19AM (#39410201)
In the general case, of course you would use arrays (static or dynamic) and some kind of "size" attribute.

But this is just 3 values in an expression and using a constant could actually be bad. Let's be a bit more practical.

  int lightness(int r, int g, int b) { return (r+g+b)/3; }
Simple and straightforward

  int lightness(int r, int g, int b) {
    const int NUMBER_ELEMENTS_AVERAGED = 3;
    return (r+g+b)/NUMBER_ELEMENTS_AVERAGED; 
  }
Ok, I guess, but I think verbose for no good reason. But not as bad as the seemingly "cleaner"

  const int NUMBER_OF_COLOR_COMPONENTS = 3;
  int lightness(int r, int g, int b) {
    return (r+g+b)/NUMBER_OF_COLOR_COMPONENTS; 
  }
Imagine that you want want to add a color component, for example to support transparency (alpha). So you set NUMBER_OF_COLOR_COMPONENTS = 4, and then, your "lightness" function breaks, the simple (r+g+b)/3 would have stayed correct. That happened because didn't get the real meaning of that "3". Even if semantically, at the time you written that code, it is the number of color components, in reality, it is the number of terms in the expression. There is r, g, b: 3 terms, so 3. Who cares how many color components there are?

Side note: I know it is the wrong formula for lightness, that's just an example.

Re:Automated Unit Test Improvement Using Large Language Mode... by barco on Saturday February 17, 2024 @09:52AM (#39409933)
If you name it `NUMBER_ELEMENTS_AVERAGED`, then when you add a new element to average, you will miss the fact that you also need to modify that value :)

You either have them on a list and calculate it dynamically based on the size, or have it as a magic number.

Re:Automated Unit Test Improvement Using Large Language Mode... by polynomial on Saturday February 17, 2024 @09:52AM (#39409927)
Sometimes a magic number is just a magic number.
Re:Automated Unit Test Improvement Using Large Language Mode... by Retric on Saturday February 17, 2024 @07:45AM (#39408946)
Many uses of numbers aren’t magic numbers. If you want to count something then setting the counter to 0 and incrementing by 1 isn’t unexplained or subject to change.
Re:Automated Unit Test Improvement Using Large Language Mode... by drowsspa on Saturday February 17, 2024 @09:17AM (#39409598)
Sometimes it's much clearer the number itself, specially when it's a mathematical formula. For instance, is

const MILLIS_PER_SECOND = 1000;

...

...

...

...

...

const durationMs = MILLIS_PER_SECOND * duration

really clearer than

const durationMs = 1000 * duration

?

Re:Automated Unit Test Improvement Using Large Language Mode... by RHSeeger on Saturday February 17, 2024 @10:06AM (#39410062)
Along the same lines, I see this a lot

    long delay = (5 * 60 * 1000); // 5 minutes, in millseconds
And it's perfectly clear to me. Now, I think the comment is really helpful there (indicating intent), but I don't think having separate constants for each of the numbers there is going to make the code better. As it is, it's very easy to read at a glance, know what it's intended to do, and determine if it's correct (should you be worried about that at the moment). Which is what's important there.
Re:Automated Unit Test Improvement Using Large Language Mode... by gregmac on Saturday February 17, 2024 @12:00PM (#39411187)
I do that as well, but typically name that variable delayMilliseconds so there's no confusion.

sleep(delay) always looks ok, but sleep(delayHours) is probably going to catch your eye as suspicious.

Re:Automated Unit Test Improvement Using Large Language Mode... by squeaky-clean on Saturday February 17, 2024 @12:42PM (#39411556)
The latter one leaves the possibility for this though

const duration = 1000 * duration

Re:Automated Unit Test Improvement Using Large Language Mode... by thebackup on Saturday February 17, 2024 @02:09PM (#39412394)
Capital M is for Mega. I would use duration_s and duration_ms.

const duration_ms = 1000 * duration_s

And _us for microsec.

const duration_us = 1000 * duration_ms

But then the tool would probably reject my code for not following the naming conventions which ”disallows using underscores in variable names”.

Guess what I wanted to say is that there are always exceptions to the rule and there should always be some way to turn off the automatic checker for certain sections of the code.

Re:Automated Unit Test Improvement Using Large Language Mode... by strulovich on Saturday February 17, 2024 @09:43AM (#39409841)
I believe even truly magic numbers don’t need to be extracted in many cases.

Say in some UI code called FooBarItem you suddenly have some call to set padding to 12. People will take this number, put it in constant and name it FOO_BAR_ITEM_PADDING = 12.

This is not better. It’s just jumping more through the code, and whatever is in the name of the constant is easily deductible from the usage pattern.

I learnt that pattern from others and nowadays I see it as useless. If you can add interesting info in the name or comments of the number, don’t bother extracting a constant.

Re:Automated Unit Test Improvement Using Large Language Mode... by lucianbr on Saturday February 17, 2024 @03:26PM (#39413219)
Don't get me started on string constants. OK_LABEL_TEXT = "OK". GET_METHOD = "GET". Bonus points if this is only used in exactly one place.

Is it really difficult to see that these are pointless? If you actually think about what you are writing, that is.

Re:Automated Unit Test Improvement Using Large Language Mode... by xLaszlo on Saturday February 17, 2024 @04:41AM (#39407934)
This is called "Goodhart's Law"
Re:Automated Unit Test Improvement Using Large Language Mode... by foofie on Saturday February 17, 2024 @06:19AM (#39408457)
> So people started writing stupid unit tests for getters and setters in Java DTOs to reach the goal.

To me that reads like your team fucked up at a very fundamental level, as they both failed to take into account the whole point of automated tests and also everyone failed to flag those nonsense tests as a critical blocker for the PR.

Unless your getters aand setters are dead code, they are already exercised by any test covering the happy path. Also, a 80% coverage target leaves out plenty of headroom to leave out stupid getter/setter tests.

A team that pulls this sort of stunt is a team that has opted to develop defensive tricks to preserve their incompetence instead of working on having in place something that actually benefits them.

Re:Automated Unit Test Improvement Using Large Language Mode... by drowsspa on Saturday February 17, 2024 @09:39AM (#39409783)
The incentives are obviously pointing towards this. And that it is so common should make you rethink your stance of "they're just incompetent".
Re:Automated Unit Test Improvement Using Large Language Mode... by dataviz1000 on Saturday February 17, 2024 @06:35AM (#39408542)
At least they didn’t do what IBM did, write tests and pay coding farms to write the code to satisfy the unit tests.
Re:Automated Unit Test Improvement Using Large Language Mode... by piersj225 on Saturday February 17, 2024 @07:27AM (#39408833)
Re:Automated Unit Test Improvement Using Large Language Mode... by dgan on Saturday February 17, 2024 @08:10AM (#39409111)
We have a mandatory Sonar scan, and when I was hired, my tech lead proudly shown me the "A" grade they have been attributed, and said something like "we have a high standard to maintain"

I have never seen such poorly written application in my 6 years of experience (and I am not only talking about style, stuff was absolutely utterly broken, while they had no clue what's wrong).

I hate Sonar with passion. It only ever should be used to report vulnerabilities, not telling me to rename variables or that i "should refactor this code duplication!" I already have a fucking backlog with Jira tickets, don't tell what i am supposed or not to do, and when i am supposed to do it.

But oh boy mangers love this stupid power burner

Re:Automated Unit Test Improvement Using Large Language Mode... by Klathmon on Saturday February 17, 2024 @08:53AM (#39409410)
I'm fighting against this now. We already use linters built and tuned by engineering, we have custom rules that solve real paint points and disabled everything that the team doesn't like or doesn't think provides value.

Then management sweeps in and is trying to add sonar, and it's a nightmare. Besides tripling our total build time to run this horrible tool, they want us to waste time rewriting our codebase to follow these insane rules like "cognitive complexity", and editor integration that takes several seconds to update after every file change.

Re:Automated Unit Test Improvement Using Large Language Mode... by stavros on Saturday February 17, 2024 @10:49AM (#39410529)
I don't understand this. Why is management telling you what to do? In our company, the managers ask/push the teams to improve some metric, but the teams are responsible for the how. The metric is usually high-level, like "reduce the number of bugs reported", not "increase code coverage".
Re:Automated Unit Test Improvement Using Large Language Mode... by therealdrag0 on Sunday February 18, 2024 @04:49PM (#39423771)
I think having cognitive complexity indicators are great. Many devs don’t think about that so having the visibility reminder is good on average. However it should not be blocking in any manner and it’s silly to drive a rewrite based on it. Engineering leaders should understand the architecture at a visceral level, know good patterns/design, and suggest refactors without static analysis tools.
Re:Automated Unit Test Improvement Using Large Language Mode... by dgan on Tuesday February 20, 2024 @04:12AM (#39439307)
"having them" is fine, being forced them down your throat is not. I mean like "your hotfix cannot be merged because you touched this piece of ancient code nobody understands and now it's complexity grew beyond the arbitrary threshold, please put all your tickets aside, and make a start refactoring this function because Sonar saud so"
Re:Automated Unit Test Improvement Using Large Language Mode... by therealdrag0 on Tuesday February 20, 2024 @12:03PM (#39443719)
Totally agree! That sounds absurd.
Re:Automated Unit Test Improvement Using Large Language Mode... by CuriouslyC on Saturday February 17, 2024 @09:16AM (#39409590)
You wanna hear retarded? I worked at an org that used Snyk/Sonar, and would block PRs on failing quality gate score. The problem was that you couldn't see why you failed quality gate score in jenkins/github, only people with Sonar accounts could , so you had to find someone with a sonar account and get them to take a screenshot of the error before you could fix it.
Re:Automated Unit Test Improvement Using Large Language Mode... by arcbyte on Saturday February 17, 2024 @02:19PM (#39412494)
Sonar os actually an incredibly powerful tool for dev teams WHEN they know how to use it and configure it according to their agreed upon standards.

When it's used thoughtlessly, as it often is, it's terrible.

Re:Automated Unit Test Improvement Using Large Language Mode... by carlossouza on Saturday February 17, 2024 @08:31AM (#39409238)
Re:Automated Unit Test Improvement Using Large Language Mode... by divan on Saturday February 17, 2024 @08:54AM (#39409415)
Must reads:

- Categorizing Variants of Goodhart's Law [1]

- Building less-flawed metrics: Understanding and creating better measurement and incentive systems [2]

[1] https://arxiv.org/abs/1803.04585

[2] https://www.sciencedirect.com/science/article/pii/S266638992...

Re:Automated Unit Test Improvement Using Large Language Mode... by jes on Saturday February 17, 2024 @08:48AM (#39409371)
> At a large insurance company I worked for, management set a target of 80% test coverage across our entire codebase. So people started writing stupid unit tests for getters and setters in Java DTOs to reach the goal.

I attended many TOC conferences in the 90s and early 2000s. Eli Goldratt was famous for saying "Tell me how you'll measure me, and I'll tell you how I will behave."

Re:Automated Unit Test Improvement Using Large Language Mode... by hibikir on Saturday February 17, 2024 @09:20AM (#39409633)
My favorite anecdote on the topic involved a codebase like this, handled by inexperienced programmers. I came into the team, and realized that a whole lot of careless logic could be massively simplified, so I sent a PR cutting the codebase by 20%, and still passing all the tests and meeting user requirements.

The problem is, the ugly, careless code extremely very well tested: 95% code coverage. My replacement had 100% code coverage... but by being far shorter, my PR couldn't pass tests, as total coverage went down, not up. The remaining code in the repo? A bunch of Swing UI code, the kind that is hard to test, and where the test don't mean anything. So facing the prospect of spending a week or two writing swing test, the dev lead decided that it was best to keep the old code somewhere in the repo, with tests pointing at it, just never called in production.

Thousands of lines of completely dead, but very well covered code were kept in the repo to keep Sonar happy.

Re:Automated Unit Test Improvement Using Large Language Mode... by littlestymaar on Saturday February 17, 2024 @09:26AM (#39409675)
My goodness…

While there are people trying with great effort to make computer as intelligent as humans, there are countless organization trying to make humans as dumb as computers by making them adhere to arbitrary numbers without giving them any agency on the evaluation of the usefulness of the metric…

Re:Automated Unit Test Improvement Using Large Language Mode... by osigurdson on Saturday February 17, 2024 @12:22PM (#39411364)
This is mostly just laziness and apathy. Don't try to learn about the problems that the business actually has, instead focus on a simple metric and the enforcement of it.
Re:Automated Unit Test Improvement Using Large Language Mode... by sangnoir on Saturday February 17, 2024 @01:44PM (#39412145)
> This is mostly just laziness and apathy.

Sometimes it is attached to incentives, like monetary rewards (bonuses and promotions). I've seen someone promoted on the back of a "high-impact" project that was bug-riddled and constituted more than half the support calls for the rest of the team for at least a year, not to mention financial penalties for the organization. It wasn't laziness or apathy, just rational actors optimizing benefits from the current rules with inadequate oversight and/or penalties for adverse outcomes.

Re:Automated Unit Test Improvement Using Large Language Mode... by osigurdson on Saturday February 17, 2024 @03:29PM (#39413249)
If you can prove that a given KPI can be mapped to the bottom line, then you really have something. Usually it isn't this simple.

Was the high impact project rushed or was it staffed with crappy devs? Or both? Usually that is the reason for bad outcomes.

Re:Automated Unit Test Improvement Using Large Language Mode... by stavros on Saturday February 17, 2024 @09:44AM (#39409845)
What's the reasoning in this? Why wouldn't they just allow you to drop the coverage percentage?
Re:Automated Unit Test Improvement Using Large Language Mode... by scarmig on Saturday February 17, 2024 @09:53AM (#39409941)
The logic looks something like "The metrics are there to measure SWE productivity and quality, if we let them change it, they will game the metrics."
Re:Automated Unit Test Improvement Using Large Language Mode... by drowsspa on Saturday February 17, 2024 @09:24AM (#39409654)
"When a metric becomes a target, it ceases to be a good metric".

A big problem is making it mandatory with huge bureaucracy to avoid its stupidness. Just last week I was battling yet another code quality tool they made mandatory: it was complaining that my res.status(200).json() wasn't setting up HSTS headers. And then I tried setting it up manually, it kept complaining, app.use(helmet()), same thing. Apparently it wanted me to write the whole backend code into a single file for it to stop complaining. And of course, HSTS is much more elegantly and automatically handled by the ingress or load balancer itself.

I could have spent a week or two flagging it as a false positive and explaining what is HSTS for upper management to approve it. I ended up just adding a res.sendJson(data, status = 200) to the prototype of the response object. Which is obviously stupid, but working in a bureaucracy-heavy sector has made me realize how much of bad software is composed of many such bad implementations combined.

Re:Automated Unit Test Improvement Using Large Language Mode... by pfdietz on Saturday February 17, 2024 @11:21AM (#39410815)
Goodhart's Law
Re:Automated Unit Test Improvement Using Large Language Mode... by seattle_spring on Saturday February 17, 2024 @12:59PM (#39411717)
> As a young dev, it taught me that focusing only on KPIs can sometimes drive behaviors that don't align with the intended goals

Something I've learned along the way as well. A few times in my career I will end up working under a manager that insists only work "that can be explicitly measured" be performed. That means they forbade library upgrades, refactors, things like that because you couldn't really prove an improvement in customer metrics or immediate changes in eng productivity.

I've also been at companies that follow that mantra more broadly and apply it to eng performance reviews. The entire culture turns into engineers focusing on either short term gains without regard for long term impact, or gaming metrics for meaningless changes and making them look important and impactful.

Important but thankless work gets left behind because, again, it's work that is not "immediately measurable." End result is a bunch of features customers hate (eg dark patterns), and a rickety codebase that everyone is disincentivised fix or improve.

Re:Automated Unit Test Improvement Using Large Language Mode... by kevin_nisbet on Saturday February 17, 2024 @01:11PM (#39411812)
Yea, I've seen this get carried away even by just individual team members.

My personal favorite was tests that a team member introduced for an object that had all the default runtime parameters in it. Think like how long should a timeout be by default, before getting overridden by instance specific settings. This team member introduced a test that checked that each value was the same as it was configured to.

So if I wanted to update or add a default, I had to write it in two places, the actual default value, and the unit test that checked if the defaults were the same as the test required.

Re:Automated Unit Test Improvement Using Large Language Mode... by salawat on Saturday February 17, 2024 @01:15PM (#39411835)
And you'd be dead wrong.

Career QA here. E2E are the absolute highest pevel of test, that take the most time to implement, have the most dependencies, and tell you the least about what is actually wrong.

If you think finding what broke is painful with full suites of unit/integration tests under the E2E suite is bad, throw those out or stop maintaining them at all. Let me know how it goes.

Re:Automated Unit Test Improvement Using Large Language Mode... by skissane on Saturday February 17, 2024 @02:53PM (#39412860)
> So people started writing stupid unit tests for getters and setters in Java DTOs to reach the goal

Ideally, the code coverage tool would have heuristics to detect trivial getter/setter methods, and filter them out, so adding tests for them won't improve code coverage. Non-trivial getters/setters (where there is some actual non-trivial logic involved) shouldn't be filtered, since they should be tested.

Although, there is room for debate about what counts as trivial. Obviously this is trivial:

    public void setUser(User user) {
       this.user = user;
    }
But should this count as trivial too?

    public void setUser(User user) {
       this.user = Objects.requireNonNull(user);
    }
Probably. What about this?

    public void setOwners(List<User> owners) {
       this.owners = List.copyOf(owners);
    }
Probably that too. Which suggests, maybe, there ought to be a configurable list of methods, whose presence is ignored when determining whether a getter/setter is trivial or not.
Re:Automated Unit Test Improvement Using Large Language Mode... by awwaiid on Saturday February 17, 2024 @03:32PM (#39413282)
True.

However we might think about this differently if we flipped it to "our standard is 20% completely untested".

Uncoverage communicates the value much better.

Re:Automated Unit Test Improvement Using Large Language Mode... by nitwit005 on Saturday February 17, 2024 @09:53PM (#39415698)
I'm convinced high coverage targets cause people to write worse code.

With Java at least, it seems to drive people to do things like not catch exceptions. It's hard to inject errors so all the catch blocks are hit.

Also makes people not want to switch to use record classes, as that feature removes class boilerplate that is easy to cover.