PineUnitPineUnit by Guardian667
A comprehensive testing framework for Pine Script on TradingView. Built with well-known testing paradigms like Assertions, Units and Suites. It offers the ability to log test results in TradingView's built-in Pine Protocol view, as well as displaying them in a compact table directly on your chart, ensuring your scripts are both robust and reliable.
Unit testing Pine Script indicators, libraries, and strategies becomes seamless, ensuring the precision and dependability of your TradingView scripts. Beyond standard function testing based on predefined input values, PineUnit supports series value testing. This means a test can run on every bar, taking into account its specific values. Moreover, you can specify the exact conditions under which a test should execute, allowing for series-based testing only on bars fitting a designated scenario.
Detailed Guide & Source Code
Quick Start
To get started swiftly with PineUnit, follow this minimalistic example.
import Guardian667/PineUnit/1 as PineUnit
var testSession = PineUnit.createTestSession()
var trueTest = testSession.createSimpleTest("True is always True")
trueTest.assertTrue(true)
testSession.report()
After running your script, you'll notice a table on your chart displaying the test results. For a detailed log output, you can also utilize the Pine Protocol view in TradingView.
--------------------------------------------------------------
T E S T S
--------------------------------------------------------------
Running Default Unit
Tests run: 1, Failures: 0, Not executed: 0, Skipped: 0
To further illustrate, let's introduce a test that's destined to fail:
var bullTest = testSession.createSeriesTest("It's allways Bull Market")
bullTest.assertTrue(close > open, "Uhoh... it's not always bullish")
After executing, the test results will reflect this intentional discrepancy:
--------------------------------------------------------------
T E S T S
--------------------------------------------------------------
Running Default Unit
Tests run: 2, Failures: 1, Not executed: 0, Skipped: 0 <<< FAILURE! - in
It's allways Bull Market
Uhoh... it's not always bullish ==> expected: , but was
This shows how PineUnit efficiently captures and reports discrepancies in test expectations.
It's important to recognise the difference between `createSimpleTest()` and `createSeriesTest()`. In contrast to a simple test, a series-based test is executed on each bar, making assertions on series values.
License
This source code is subject to the terms of the Mozilla Public License 2.0 at mozilla.org
@ Guardian667
A Personal Note
As a software developer experienced in OO-based languages, diving into Pine Script is a unique journey. While many aspects of it are smooth and efficient, there are also notable gaps, particularly in the realm of testing. We've all been there: using `plotchar()` for debugging, trying to pinpoint those elusive issues in our scripts. I've come to appreciate the value of writing tests, which often obviates the need for such debugging. My hope is that this Testing Framework serves you well and saves you a significant amount of time, more that I invested into developing this "baby."
Testing
matrixautotableLibrary "matrixautotable"
Automatic Table from Matrixes with pseudo correction for na values and default color override for missing values. uses overloads in cases of cheap float only, with additional addon for strings next, then cell colors, then text colors, and tooltips last.. basic size and location are auto, include the template to speed this up...
TODO : make bools version
var string group_table = ' Table'
var int _tblssizedemo = input.int ( 10 )
string tableYpos = input.string ( 'middle' , '↕' , inline = 'place' , group = group_table, options= )
string tableXpos = input.string ( 'center' , '↔' , inline = 'place' , group = group_table, options= , tooltip='Position on the chart.')
int _textSize = input.int ( 1 , 'Table Text Size' , inline = 'place' , group = group_table)
var matrix _floatmatrix = matrix.new (_tblssizedemo, _tblssizedemo, 0 )
var matrix _stringmatrix = matrix.new (_tblssizedemo, _tblssizedemo, 'test' )
var matrix _bgcolormatrix = matrix.new (_tblssizedemo, _tblssizedemo, color.white )
var matrix _textcolormatrix = matrix.new (_tblssizedemo, _tblssizedemo, color.black )
var matrix _tooltipmatrix = matrix.new (_tblssizedemo, _tblssizedemo, 'tool' )
// basic table ready to go with the aboec matrixes (replace in your code)
// for demo purpose, random colors, random nums, random na vals
if barstate.islast
varip _xsize = matrix.rows (_floatmatrix) -1
varip _ysize = matrix.columns (_floatmatrix) -1
for _xis = 0 to _xsize -1 by 1
for _yis = 0 to _ysize -1 by 1
_randomr = int(math.random(50,250))
_randomg = int(math.random(50,250))
_randomb = int(math.random(50,250))
_randomt = int(math.random(10,90 ))
bgcolor = color.rgb(250 - _randomr, 250 - _randomg, 250 - _randomb, 100 - _randomt )
txtcolor = color.rgb(_randomr, _randomg, _randomb, _randomt )
matrix.set(_bgcolormatrix ,_yis,_xis, bgcolor )
matrix.set(_textcolormatrix ,_yis,_xis, txtcolor)
matrix.set(_floatmatrix ,_yis,_xis, _randomr)
// random na
_ymiss = math.floor(math.random(0, _yis))
_xmiss = math.floor(math.random(0, _xis))
matrix.set( _floatmatrix ,_ymiss, _xis, na)
matrix.set( _stringmatrix ,_ymiss, _xis, na)
matrix.set( _bgcolormatrix ,_ymiss, _xis, na)
matrix.set( _textcolormatrix ,_ymiss, _xis, na)
matrix.set( _tooltipmatrix ,_ymiss, _xis, na)
// import here
import kaigouthro/matrixautotable/1 as mtxtbl
// and render table..
mtxtbl.matrixtable(_floatmatrix, _stringmatrix, _bgcolormatrix, _textcolormatrix, _tooltipmatrix, _textSize ,tableYpos ,tableXpos)
matrixtable(_floatmatrix, _stringmatrix, _bgcolormatrix, _textcolormatrix, _tooltipmatrix, _textSize, tableYpos, tableXpos) matrixtable
Parameters:
_floatmatrix : float vals
_stringmatrix : string
_bgcolormatrix : color
_textcolormatrix : color
_tooltipmatrix : string
_textSize : int
tableYpos : string
tableXpos : string
matrixtable(_floatmatrix, _stringmatrix, _bgcolormatrix, _textcolormatrix, _textSize, tableYpos, tableXpos) matrixtable
Parameters:
_floatmatrix : float vals
_stringmatrix : string
_bgcolormatrix : color
_textcolormatrix : color
_textSize : int
tableYpos : string
tableXpos : string
matrixtable(_floatmatrix, _stringmatrix, _bgcolormatrix, _txtdefcol, _textSize, tableYpos, tableXpos) matrixtable
Parameters:
_floatmatrix : float vals
_stringmatrix : string
_bgcolormatrix : color
_txtdefcol : color
_textSize : int
tableYpos : string
tableXpos : string
matrixtable(_floatmatrix, _stringmatrix, _txtdefcol, _bgdefcol, _textSize, tableYpos, tableXpos) matrixtable
Parameters:
_floatmatrix : float vals
_stringmatrix : string
_txtdefcol : color
_bgdefcol : color
_textSize : int
tableYpos : string
tableXpos : string
matrixtable(_floatmatrix, _txtdefcol, _bgdefcol, _textSize, tableYpos, tableXpos) matrixtable
Parameters:
_floatmatrix : float vals
_txtdefcol : color
_bgdefcol : color
_textSize : int
tableYpos : string
tableXpos : string
debuggerDEBUGGER is a library to help print debug messages to a console.
This library provides an easy-to-use interface to print your debugging messages to a console in the chart. Special attention has been given to printing series and arrays easily.
A debugger is a valuable tool when working on scripts and getting into trouble. Unfortunately, TradingView does not provide an interactive debugger, and does not provide a console to use the oldest trick in the debugging book: print statements. This library provides you with the latter tool, print statements.
As a bonus, the library also provides a way to show labels in the chart next to the pricing action.
For more information and examples of usage, check the description in the header comments.