At Suiteworld I saw a presenter doing unit tests o...
# suitescript
s
At Suiteworld I saw a presenter doing unit tests on a map/reduce script in netsuite via Jasmine and Karma (inside intellij). Has anyone set this up before?
j
I'm interested in how they set that up, because the slides for that presentation consist of just a single page that says "SuiteScript module makes testing easy"
😂 2
😆 1
c
You can setup unit tests to test business logic but there's no reason to test the map/reduce script itself
basically extract the JS w/ no netsuite code and run unit tests against it.. whether or not netsuite's methods are working isn't something you should test
j
I discussed with eric about facilitating testing by reading record / sublist data into a decoupled abstraction layer, manipulating it there, and putting it back when you're done. I'm still pretty curious about that presentation 🙂
s
@creece There's always a reason to test haha. That said, I'm mainly curious how she was able to create unit testing for userevent scripts, client scripts, and all other script types. Seems very powerful, and I'd really like to copy that because she had the ability to write a unit test for every thing.
Creece, the actual netsuite method calls would be beneficial for, and this happens often, someone creates a required field. Integration runs, doesn't set the field, and breaks
s
if you're calling 'real' netsuite code then it's not a unit test - it's an integration test. Also, there is a 'decoupled abstraction layer' for NS records - it's called NFT NSDAL 🙂
I used to use jasmine/karma or mocha/chai/sinon for our NS unit tests but have recently started using jest instead. It's a single package that gives me what used to take several packages.
s
@stalbert Hey, excuse my ignorance, but what would be the different between unit test and integration test?
s
the definition can be debated, but the one I use is that a 'unit test' does not test any dependencies (they should be mocked). On the other hand, an 'integration test' is any test where dependencies are not mocked.
For example, say you have a function A() that just adds two numbers, and doesn't depend on any NS APIs or anything else. Tests of function A() would all be unit tests
Say you have a function B() which does stuff of its own AND calls something like record.load(). A unit test means trying to only verify behavior of your code in B(), not verifying that NS record.load() works.
Hence, a unit test of B() would require a mock
record.load()
to be deemed a unit test.
if you test B() without mocking
record.load()
then you have an integration test, because this invokes not only the code you wrote in B() but also invokes NS's
record.load()
code.
👍🏼 1
Hope that all makes some sense.
Also, here one can say
B() depends upon record.load()
or "N/record is a dependency of function B()"
c
unit tests test the actually method code and integration tests just test the output you expect
there's always reason to test but there's only a reason to test YOUR business logic. You shouldn't be testing netsuite is what I am saying
s
yes, I like to believe NS has their own unit tests for their code!
c
we all know that isn't true
😆 1
well definitely not any coverage to speak of on the js side... maybe the java side has some
i'd only really write tests for critical business logic honestly. You have to write code in a different way in order to do unit testing for a lot of things. If you're testing sublist test for example, you'd have to get all of your line data in a native JS data structure and pass that to a method that does the business logic so you can test that way.. so you've decoupled the netsuite side from the business logic and you can easily test
👍🏼 1
s
yes, that's one reason NFT exists. Since it surfaces line data as a JS array of objects it's already ready for testing - you just supply plain js (e.g. itemsublist = [{field:1}]) to your unit under tests without any additional mocking needed.
so that removes the need for some NS interaction and allows a broader range of pure unit tests to be trivially crafted. However often it makes sense to call other NS apis even when you have NSDAL objects.
NFT itself doesn't have the luxury of this abstraction layer (because it IS the abstraction layer) so here is a small example of unit tests for NFT which have to mock the underlying NS apis: https://github.com/ExploreConsulting/netsuite-fasttrack-toolkit-ss2/blob/a989fcf243089cb90d601ed2fe09d5f908fdeb6d/test/nsdal.test.ts
I've just started playing with jest here, and I'm impressed with their easy implementation for mocking and how it is trying to embrace the JS module system to pull in mocks
having done a lot of NS api mocking in the SS1.0 days, my initial experience with jest has been refreshing.
j
Yeah I was just looking at how you got it to work in node when each file has an
import ... from 'N/record'
. Never used jest but I'm guessing this part of the config
"N/(.*)": "<rootDir>/../__mocks__/N/$1"
intercepts and rewrites import paths?
s
that is for typescript to find the modules
sorry,that was jest config.. yes that's so that jest finds the mocks when code asks for "N/..."
NFT for SS1 unit tests rely on karma and running in the browser. That works but am trying to drop need for browsers for NFT-SS2
client script unit tests may need a browser, but don't need it for server scripts (which is the vast majority of scripting I do)
c
i used mocha/should and got 1.0 unit tests working well
but no netsuite mocking
no unit tests should need a browser if you use a node based testing framework
s
anyway @screnshaw you should be able to git clone that repo I mentioned and do
npm test
for a working example.
👍🏼 1
One of the challenges I ran into with doing pure node based tests is node uses commonjs modules and NS AMD
that's one spot where TS swoops in to save the day - it outputs commonjs for unit testing purposes while uses AMD for the normal NS build
c
yeah i only did 1.0 with it and haven't been writing tests for 2.0. You may have to change define -> require or something
thats interesting
j
That's how I have my project set up 🙂. I leave my tsconfig.json on commonjs for testing in node with ts-node, then for deployment I have a gulp script that changes it to amd with gulp-typescript
s
I'm just using a separate`tsconfig.json` for tests vs normal - so far have avoided need for a gulp task or similar for it. Though it's early days - I only added this unit test stuff to NFT-SS2 a few days ago. Like @creece I have been delaying on unit testing in SS2 unlike SS1.
j
Yeah, having the dependencies in the import path makes SS2.0 a bit trickier to unit test because there's no
N/record
for node to require. A couple months ago I fiddled around with mocking netsuite modules for testing in mocha and I ended up writing a script that rewrote import paths to the "mock" module. I came away thinking it was too hacky to continue practicing
s
That is a lot to take in haha. It seems that it will be a lot more involved than I thought, but I guess it's better to start now, than regret it later lol
s
I'm happy enough with jest's approach to it (mocks) so far
it helped me go from too-long-without-any-tests-for-NFT-SS2 to having at least a tiny few!
c
Yep can't complain if you have some tests
Most likely 99% of netsuite code does not
s
Yes, well for NFT-SS1 we were strict about it - a feature could not be added to the library unless it had some unit tests. would like to get to that spot with NFT-SS2 as well.
but I agree, I think it's only a tiny percentage of NS code that has unit tests overall
in the case of NFT it worries me more because it's library code for reuse, so the benefit to unit testing is amplified.
c
yeah i started to write tests for everything then just went to the critical business functionality. If you have your own product you can get that luxury which is awesome but MOST clients aren't gonna see the value and expense bc they aren't technical. Trying to explain unit tests to a business drone is near impossible.