RSS

Zawsze pracuj z włączonymi asercjami

Liczba odsłon: 101

Sytuacje wy­jąt­ko­we oraz aser­cje po­zwa­la­ją pro­gra­mi­ście za­pa­no­wać nad prze­twa­rza­ny­mi da­ny­mi i za­pew­nić nie­za­wod­ne dzia­ła­nie pro­gra­mu. Z tej pa­ry, aser­cje cie­szą się jed­nak zde­cy­do­wa­nie mniej­szą po­pu­lar­noś­cią, mie­rzo­ną czę­sto­ścią wy­ko­rzys­ta­nia w pro­gra­mach. Tymcza­sem roz­sąd­nie uży­te po­tra­fią skró­cić czas wy­kry­wa­nia i diag­no­zo­wa­nia prob­le­mów, bez zmniej­sza­nia wy­daj­noś­ci opro­gra­mo­wa­nia w śro­do­wis­ku pro­duk­cyj­nym.

Asercje to wy­ra­że­nia lo­gicz­ne, któ­rych war­tość mu­si być praw­dzi­wa w da­nym miej­scu. Asercje re­pre­zen­tu­ją za­ło­że­nia (ang. asser­tions) do­ty­czą­ce dzia­ła­nia pro­gra­mu. Programis­ta w cza­sie ko­do­wa­nia mo­że wie­dzieć, że w kon­kret­nym miej­scu pew­na war­tość po­win­na speł­niać pew­ne za­ło­że­nia, nie­zbęd­ne do dal­sze­go po­praw­ne­go dzia­ła­nia pro­gra­mu. Sprawdzanie tych za­ło­żeń za po­mo­cą sytu­acji wy­jąt­ko­wych jest po­zba­wio­ne sen­su, gdyż w po­praw­nie na­pi­sa­nym pro­gra­mie zaw­sze bę­dą one speł­nio­ne. Problem sta­no­wi je­dy­nie fa­za ko­do­wa­nia i tes­to­wa­nia, gdy błę­dy w in­nych mo­du­łach mo­gą pro­pa­go­wać i na­ru­szać te za­ło­że­nia.

W za­leż­noś­ci od ję­zy­ka pro­gra­mo­wa­nia aser­cje są al­bo umiesz­cza­ne w ko­dzie po­śred­nim i uwzględ­nia­ne lub omi­ja­ne w cza­sie reali­zac­ji (tak dzia­ła na przy­kład ma­szy­na wir­tu­al­na ję­zy­ka Java), al­bo kom­pi­lo­wa­ne wa­run­ko­wo w za­leż­noś­ci od kon­fi­gu­rac­ji śro­do­wis­ka bu­do­wa­nia (C, C++, C♯). Jeżeli są wy­łą­czo­ne, ich wpływ na wy­daj­ność bę­dzie al­bo zni­ko­my (Java) al­bo ża­den (po­zo­sta­łe ję­zy­ki).

Aktywne aser­cje po­zwa­la­ją pro­gra­mi­ście upew­nić się, że pro­gram dzia­ła zgod­nie z za­ło­że­nia­mi oraz prze­wi­dy­wa­nia­mi, a wszyst­kie war­toś­ci le­żą we właś­ci­wych prze­dzia­łach. Dlatego pro­gra­mis­ta po­wi­nien te­sto­wać swój pro­gram (i udo­stęp­niać go do pierw­szych te­stów, nie uwzględ­nia­ją­cych we­ry­fi­ka­cji wy­daj­noś­ci) zaw­sze w wer­sji DEBUG, za­wie­ra­ją­cej aser­cje. Dla apli­kac­ji C i C++ uzys­ku­je się to przez nie­zde­fi­nio­wa­nie sym­bo­lu NDEBUG w cza­sie kom­pi­la­cji (do­myśl­na kom­pi­la­cja uwzględ­nia aser­cje); op­cjo­nal­nie moż­na też zde­fi­nio­wać sym­bol DEBUG (nie­któ­re bi­blio­te­ki nie trzy­ma­ją się stan­dar­du i do­myśl­nie wy­łą­cza­ją aser­cje). W przy­pad­ku apli­kac­ji .NET w śro­do­wis­ku pro­gra­mi­stycz­nym na­le­ży wy­brać pro­fil Debug za­miast Release.

Środowi­sko ma­szy­ny wir­tu­al­nej Java za­cho­wu­je się tro­chę ina­czej. Asercje są zaw­sze umiesz­cza­ne w ko­dzie po­śred­nim, na­le­ży je je­dy­nie włą­czyć w ma­szy­nie wir­tu­al­nej. Uzyskuje się to za po­mo­cą pa­ra­me­tru -ea (ang. enable assertions) po­le­ce­nia java. Jeżeli uru­cha­mia­my apli­kac­je Java EE, aser­cje na­le­ży włą­czyć w kon­te­ne­rze, do­łą­cza­jąc pa­ra­metr -ea do wier­sza po­le­ceń JVM. Na przy­kład, w kon­te­ne­rze Glass­fish uzys­ku­je się to w pa­ne­lu kon­fi­gu­ra­cyj­nym Configu­ra­tions / ser­ver-con­fig / JVM Settings / JVM Options. Z kolei w kon­te­ne­rze Wildfly uzys­ku­je się to w zbio­rze standalone.conf (lub standalone.conf.bat w sys­te­mie Win­dows), do­da­jąc -ea do zmien­nej śro­do­wis­ko­wej JAVA_OPTS.

Co cie­ka­we – i nie ta­kie oczy­wis­te – aser­cje są po­ży­tecz­ne na­wet wte­dy, gdy nie są uaktyw­nio­ne lub kom­pi­lo­wa­ne. Pełnią one bo­wiem ro­lę po­dob­ną do ko­men­ta­rzy, przy tym bar­dzo zwięz­łych i sfor­ma­li­zo­wa­nych. Są na­wet lep­sze od ko­men­ta­rzy, gdyż pod­le­ga­ją pod­świet­la­niu skład­ni, pod­po­wia­da­niu nazw oraz we­ry­fi­ka­cji skład­nio­wej pod­czas kom­pi­la­cji pro­gra­mu. Strategicz­nie umiesz­czo­ne aser­cje sta­no­wią za­tem pierw­szy etap tes­to­wa­nia jed­nost­ko­we­go.