code: def test_bollinger_bands(self, window_length, k, mask_last_sid):
      closes = self.closes(mask_last_sid=mask_last_sid)
      mask = ~np.isnan(closes)
      bbands = BollingerBands(window_length=window_length, k=k)
  
      expected = self.expected_bbands(window_length, k, closes)
  
      self.check_terms(
          terms={
              "upper": bbands.upper,
              "middle": bbands.middle,
              "lower": bbands.lower,
          },
          expected={
              "upper": expected[0],
              "middle": expected[1],
              "lower": expected[2],
          },
          initial_workspace={
              USEquityPricing.close: AdjustedArray(
                  data=closes,
                  adjustments={},
                  missing_value=np.nan,
              ),
          },
          mask=self.build_mask(mask),
      )
  
imports: from __future__ import division
  from nose_parameterized import parameterized
  from six.moves import range
  import numpy
  import pandas
  import talib
  from numpy.random import RandomState
  from zipline.lib.adjusted_array import AdjustedArray
  from zipline.pipeline.data import USEquityPricing
  from zipline.pipeline.factors import BollingerBands, Aroon, FastStochasticOscillator, IchimokuKinkoHyo, LinearWeightedMovingAverage, RateOfChangePercentage, TrueRange, MovingAverageConvergenceDivergenceSignal, AnnualizedVolatility, RSI
  from zipline.testing import check_allclose, parameter_space
  from zipline.testing.fixtures import ZiplineTestCase
  from zipline.testing.predicates import assert_equal
  from .base import BaseUSEquityPipelineTestCase
label_desc: Use image node_id 3 for calling the BollingerBandsTestCase obj's underlying member method code with example usage: obj.test_bollinger_bands(window_length, k, mask_last_sid) without return types